一、greenrobot介绍

greenrobot相关信息较少,可以确信是一个开源组织。官网:http://greenrobot.org/。
greenrobot主要开发并维护了3个Android开源库,即greenDAO、EventBus、和Essentials。三个开源库都可以在GitHub上进行下载。本节讲解其中最著名的EventBus。

二、EventBus概述

EventBus的官方解释是:

“EventBus is a central publish/subscribe event system for Android. Events are posted (post(Object)) to the bus, which delivers it to subscribers that have a matching handler method for the event type. To receive events, subscribers must register themselves to the bus using register(Object). Once registered, subscribers receive events until unregister(Object) is called. Event handling methods must be annotated by Subscribe, must be public, return nothing (void), and have exactly one parameter (the event).”

从中可以看出,EventBus是一个专门为Android优化的“发布/订阅”模式的事件总线(原文:EventBus is a publish/subscribe event bus optimized for Android)。。事件被发布到事件总线(bus),然后事件总线将事件发送给符合条件的订阅者,这里的符合条件是通过订阅者重写的处理方法的方法签名来判断的。

这里根据EventBus在GitHub主页(https://github.com/greenrobot/EventBus)上的介绍进行翻译,EventBus的特性包括:
 简化了组件间的通讯
 分离了事件的发送者和接受者;
 在Activity、Fragment和线程中表现良好;
 避免了复杂的和易错的依赖关系和声明周期问题;
 使得代码更简洁;
 更快;
 更小(约50k的jar包)
 实际上超过1亿的app证明了它的性能;
 有高级属性,例如发布线程、订阅属性等。

三、相关资料

 eventbus-3.0.0-beta1.jar:eventbus 3.0的类库,放入工程中的libs文件夹即可使用;
 eventbus-3.0.0-beta1-javadoc:eventbus3.0的离线API
 eventbus-3.0.0-beta1-sources:eventbus3.0的源码
 源码地址:https://github.com/greenrobot/EventBus
Github上的源码下载后由于诸多依赖关系,本人尝试多次后仍未能通过编译。所以,推荐使用jar包的方式进行使用。
资料下载:eventbus相关jar包

四、 EventBus使用

4.1 API解析

(1)ThreadMode
ThreadMode是enum类型,用在事件处理函数的方法注解中,标示事件处理函数是那种类型。每一个订阅者都通过事件处理函数来接收和处理事件,而事件处理函数有4种模式:
 Async
这种模式下,订阅者的事件处理函数运行在新开启的线程中,而不论发布者是UI线程还是子线程。
 BackgroundThread
这种模式与Async的区别在于,如果发布者不是UI线程,那么订阅者的事件处理函数直接在发布者的线程中运行,不必新开线程。
 MainThread
在UI线程中运行事件处理函数。
 PostThread
在与发布者相同的线程中运行.
(2)EventBus
有3种初始化方式。
 单例模式的默认配置

EventBus eventBus =EventBus.getDefault();//本质是调用了new EventBus()

 new方式

EventBus eventBus =new EventBus();//默认配置

 建造者模式的自定义配置

EventBusBuilder busBuilder=EventBus.builder();//生成建造者
busBuilder.eventInheritance(false);//默认是true,支持事件继承的。
busBuilder.logNoSubscriberMessages(false);//默认是true,没有订阅者时打印相关log
……
EventBus eventBus=busBuilder.build();

这里要注意的是,通过单例模式生成默认eventBus具有线程的全局单例特性。实践中,通过new或者建造者模式生成的eventBus可以放在Application中初始化。
EventBus的常用方法有:

 post(java.lang.Object event):发布事件。
 postSticky(java.lang.Object event):发布sticky事件
 register(java.lang.Object subscriber):注册订阅者
 removeAllStickyEvents():清除所有sticky事件
 removeStickyEvent(java.lang.Class eventType):清除某种类型的所有sticky事件
 removeStickyEvent(java.lang.Object event):清除某个sticky事件
 unregister(java.lang.Object subscriber):解除订阅者

(3)EventBusBuilder
用于配置EventBus的属性。

4.2 基本用法

EventBus使用的步骤是:声明事件→注册订阅者→发布事件。最简单的用法是用默认的单例模式。
(1)第一步,声明事件:
事件即定义用于传递的某种消息的类。这里定义了3个简单的类FirstEvent、SecondEvent、ThirdEvent,三者形式相同。

/*** Created by CaoYanfeng on 2016/3/15.*/
public class FirstEvent {private String mMsg;public FirstEvent(String msg) {// TODO Auto-generated constructor stubmMsg = msg;}public String getMsg(){return mMsg;}
}

(2)注册订阅者
例如,在Activity的onCreat()中进行注册:

EventBus.getDefault().register(this);

注意,订阅者必须实现至少一个事件处理函数,否则会报错。在Activity中实现4种类型的事件处理函数:

    /**必须使用标记符。这表明要在UI线程中处理*/@Subscribe(threadMode = ThreadMode.MainThread)public void onEventMainThread(FirstEvent event) {String msg = "onEventMainThread收到了消息:" + event.getMsg();Log.d("harvic", msg);}
/**必须使用标记符。这表明要在与发布线程相同的线程中处理*/
@Subscribe(threadMode = ThreadMode.PostThread)public void onEvent(ThirdEvent event) {Log.d("harvic", "OnEvent收到了消息:" + event.getMsg());}
/**必须使用标记符。这表明如果是在UI线程中发布,则在新线程中运行*/@Subscribe(threadMode = ThreadMode.BackgroundThread)public void onEventBackgroundThread(SecondEvent event){Log.d("harvic", "onEventBackground收到了消息:" + event.getMsg());
}
/**必须使用标记符。在新线程中运行*/@Subscribe(threadMode = ThreadMode.Async)public void onEventAsync(SecondEvent event){Log.d("harvic", "onEventAsync收到了消息:" + event.getMsg());}

(3)发布事件
发布事件可以在UI线程、子线程。例如:

EventBus.getDefault().post(new FirstEvent("FirstEvent btn clicked"));

4.3 Sticky事件

“声明事件→注册订阅者→发布事件”的顺序限制了EventBus的使用范围。例如,Activity1跳转到Activity2的过程中,需要将事件从Activity1发布,而需要在Activity2中进行订阅。由于跳转前Activity2并没有初始化,不能注册为订阅者。
将事件发布为Sticky事件,本质上是将事件保存到了EventBus中的Map数据结构。查看EventBus源码,可以印证:
private final Map<Class<?>, Object> stickyEvents;
这样,相当于将事件放入了缓存,然后再从缓存中取得该事件。
(1)发布sticky事件
EventBus.getDefault().postSticky(new StickyEvent(“我是StickyEvent!”));
(2)取出sticky事件
EventBus.getDefault().removeStickyEvent(StickyEvent.class);
StickyEvent stickyEvent=EventBus.getDefault().getStickyEvent(StickyEvent.class);
String msg = “收到了事件:” + stickyEvent.getMsg();
Log.d(“harvic”, msg);
EventBus中包含了几个清除Sticky事件的方法,见【API解析】。
##4.4 事件的继承性##
通过默认方式生产的EventBus是默认配置,这些配置保证了如果发布的是子类对象,订阅的是父类对象,仍然可以接收到目标事件,因为子类向上进行类型转换是不会出问题的(反之则不一定)。如果要阻止这种情况,即保证发布子类对象,而订阅父类对象时不必接收目标事件,那就不能用默认配置,而需要用构造者模式。

EventBusBuilder busBuilder=EventBus.builder();//生成建造者
busBuilder.eventInheritance(false);//默认是true,这里设置为false。
EventBus eventBus=busBuilder.build();

#五、 EventBus源码分析#
EventBus本质上是观察者模式。源码分析见:android 开源工具 EventBus的使用和源码分析。

六、 Demo说明

这里我写了个Demo,下载地址为:EventBusDemo。
工程EventBusDemo实现两个Activity跳转。逻辑如下:
 FirstEvent、SecondEvent、ThirdEvent、StickyEvent、ThirdEventChild分别是事件类,ThirdEventChild继承自ThirdEvent;App中采用建造者模式生成了EventBus,并阻止了继承模式;

 MainActiy将自己作为订阅者注册到默认的EventBus中,并实现了多个处理事件;
 MainActiviy在跳转时发布了sticky事件,SecondActity取出了sticky事件;
 SecondActivity的3个按钮分别发布了几个事件,用于测试默认的EventBus、建造者模式生成的EventBus。

参考

[1]EventBus使用详解(一)——初步使用EventBus;
[2]https://www.zhihu.com/question/32179258/answer/54989242;
[3] http://www.2cto.com/kf/201503/380502.html。

请我喝咖啡

如果觉得写得不错,可以扫描我的微信二维码请我喝咖啡哦~


或者点击 打赏地址 请我喝杯茶~

【Android开发】greenrobot三大开源利器详解(一)——EventBus相关推荐

  1. android什么控件能够输入多行文字,Android开发:文本控件详解——EditText(一)基本属性...

    一.简单实例: EditText输入的文字样式部分的属性,基本都是和TextView中的属性一样. 除此之外,EditText还有自己独有的属性. 二.基本属性: hint 输入框显示的提示文本 te ...

  2. Android 开发架构-MVC MVP MVVM详解

    何为架构 架构,即程序的逻辑组织结构,是指导开发过程中划分程序逻辑模块的关键,好的架构要使程序达到高内聚低耦合的设计目标.例如一个人,身体的骨骼即为身体的架构,有了基本骨架之后,才可以决定在头颅里开发 ...

  3. Android开发-CardView卡片View的详解,头条三面技术四面HR

    CardView一般用于需要显示阴影效果的UI,此外CardView还提供了圆角的功能.(嘿嘿,这东西还能直接设置成圆形,可以简单的弄成圆形View).CardView其实本身是使用FrameLayo ...

  4. 线程对象Android 开发之多线程处理、Handler 详解

    发一下牢骚和主题无关: 每日一道理 毅力,是千里大堤一沙一石的凝聚,一点点地累积,才有前不见头后不见尾的壮丽:毅力,是春蚕吐丝一缕一缕的环绕,一丝丝地坚持,才有破茧而出重见光明的辉煌: 毅力,是远航的 ...

  5. Android 开发之多线程处理、Handler 详解

    Android开发过程中为什么要多线程 我们创建的Service.Activity以及Broadcast均是一个主线程处理,这里我们可以理解为UI线程.但是在操作一些耗时操作时,比如I/O读写的大文件 ...

  6. Android开发实现高德地图定位详解

     一. 要实现高德地图定位呢,首先需要做好以下几步准备: 1. 在高德开放平台注册帐号 注册地址:http://lbs.amap.com 2. 在开发中下载Android平台下的地图SDK和定位S ...

  7. Android开发之触摸事件处理机制详解

     android触碰消息传递机制 用户的每次触碰(onClick,onLongClick,onScroll,etc.)都是由一个ACTION_DOWN+n个ACTION_MOVE+1个ACTION ...

  8. 软件开发中的开源协议详解!

    作者:pdai cnblogs.com/pengdai/p/9227404.html 开源不等于免费!为了加速我们的开发,我们会使用开源的软件和源码: 为避免商业风险,需要在使用时了解第三方如软件协议 ...

  9. Android开发笔记之:Log图文详解(Log.v,Log.d,Log.i,Log.w,Log.e)

    本篇文章是对Android中的Log进行了详细的分析介绍,需要的朋友参考下 在Android群里,经常会有人问我,Android Log是怎么用的,今天我就把从网上以及SDK里东拼西凑过来,让大家先一 ...

最新文章

  1. 误差、方差、偏差、噪声、训练误差+验证误差、偏差方差窘境、错误率和误差、过拟合与欠拟合
  2. 2020-12-17 Halcon初学者知识【4】区域和分割
  3. Hadoop 2.2.0 集群搭建
  4. Python类的静态属性、类方法、静态方法
  5. js动态获取时间的方式
  6. GIS理论(墨卡托投影、地理坐标系、地面分辨率、地图比例尺、Bing Maps Tile System)转载...
  7. 虚拟服务器配置推荐,如何选择虚拟主机配置
  8. 由于应用程序配置不正确
  9. Struts框架下定时任务
  10. 怎么把网页转成PDF?
  11. Android Studio无法检测到魅族手机的解决方法
  12. 计算机学科a类排名,哈工大17个学科排名位列A类
  13. oracle查询时间段差,关于oracle数据库中进行查询的时候出现效率特别差的一种情况...
  14. java环境变量配置_Java环境变量配置终极版
  15. WPS个人版如何启用VBA(宏)
  16. mysqldb python linux,Linux下安装 MySQLdb模块
  17. 不可思议的每日培训(1)——日复一日的每日分享
  18. vivo是安卓手机吗_安卓手机系统升级必要吗?看看这个就知道
  19. @Value为啥取不到值
  20. WordPress博客文章页如何添加OG协议标签

热门文章

  1. 【详细图文】Ubuntu 16.04更改下载源 解决软件包下载慢问题
  2. html怎么设置出场动画,CSS3 元素出现动画实例
  3. 【有利可图网】PS教程:PS制作气泡黑板效果
  4. Tobii Studio眼动仪教程 - 真正的测谎机器
  5. 生成6位纯数字验证码的三种方式
  6. Ubuntu 提取CHM并转PDF的方法
  7. 更新linux内核方法
  8. 关于uniapp发送post请求无响应的问题
  9. 情侣间的计算机游戏,促进一下情侣之间的感情 ? 你可以玩这些游戏啦!
  10. MMC5603地磁传感器调试日志