关于 EventBus 在开发中经常会选择使用它来进行模块间通信、解耦。平常使用这个库只是很浅显的操作三部曲,register,post,unregister。来达到开发目的。始终有种不明确,模糊的操作感。因此准备对EventBus进行一个深入,全面的理解,消除模糊,片面感,让以后在使用这个库的时候,有更好的掌握和使用。并记录下来,方便以后查阅。关于EventBus会分两章进行记录,本篇文章,是对EventBus的使用做一个全面的介绍,另一篇文章则会对EventBus库的源码进行分析,看看他的实现原理是什么样的。
EventBus 是一个开源库,它利用发布/订阅者者模式来对项目进行解耦。它可以利用很少的代码,来实现多组件间通信。android的组件间通信,我们不由得会想到handler消息机制和广播机制,通过它们也可以进行通信,但是使用它们进行通信,代码量多,组件间容易产生耦合引用。关于EventBus的工作模式,这里引用一张官方图帮助理解。

上面这张图还是很好理解的,Publisher(发布者)通过post()方法,把Event事件发布出去,Subscriber(订阅者)在onEvent()方法中接收事件,可能现在你对Publisher,Subscriber, onEvent()这几个词还是不理解,没关系,别着急,放下看慢慢的你就懂了。
为什么会选择使用EventBus来做通信?
- 简化了组件间交流的方式
- 对事件通信双方进行解耦
- 可以灵活方便的指定工作线程,通过ThreadMode
- 速度快,性能好
- 库比较小,不占内存
- 使用这个库的app多,有权威性
- 功能多,使用方便
现在,我们就来体验EventBus的强大之处吧。
导入项目
在build.gradle文件中导入EventBus库。
在项目的混淆文件中,加入EventBus 的混淆规则,这个千万别忘了,不然会出现,debug版本测试OK,release版本subscriber 收不到消息等诡异问题。
EventBus库中最重要的三个点,分别是subscriber(订阅者),事件(消息),publisher(发布者)。主要理解这三者的关系即可。
subscriber ——> EventBus 的register方法,传入的object对象
事件(Event)——> EventBus 的post方法,传入的类型。
publisher(发布者)——> EventBus的post方法。
- 创建一个事件类型,消息事件类型可以是string,int等常见类,也可以是自己自定义一个事件类,方便管理。这边演示,创建了一个EventMessage事件类。
- 在需要订阅事件的模块中,注册eventbus。
MainActivity.java
关于EventBus的注册问题,说几点。
- 注册完了,在不用的时候千万别忘了unregister。
- 不能重复注册。注册之后,没有unregister,然后又注册了一次。
- register与unregister的时间根据实际需求来把控,官方的例子是在onStart()回调方法进行注册,onStop()回调方法进行unregister(),这边根据需求做了改动。
在需要接受事件的类中进行好register之后,需要在该类中创建一个方法来接收事件消息。
创建的这个方法是有要求的。要求有如下几点。
- 该方法有且只有一个参数。
- 该方法必须是public修饰符修饰,不能用static关键字修饰,不能是抽象的(abstract)
- 该方法需要用@Subscribe注解进行修饰。
关于Subscribe注解的介绍,将在后面结合实例进行讲解。
3. 在需要发送事件的地方,调用EventBus的post(Object event),postSticky(Object event)来通知订阅者。
SecondActivity.java
注意,该例子中,我使用了,EventBus.getDefault()方法,该方法会获取一个单例。所以才可以随时使用,如果不是用这种单例模式,需要想办法把订阅者(Subscriber)注册时用的EventBus的引用传给需要发送事件的模块中,简而言之就是Subscriber用的eventbus 和post方法需要的eventbus需要是同一个eventbus。
我们跑下代码测试一下。结果如下。

发现使我们想要的结果。那现在关于EventBus的基本使用,就明白了,主要就是三个部分,一个部分是Subscriber,需要在Subscriber类中进行register和unregister操作。一部分是在Subscriber中需要创建一个方法来接收事件信息,最后一部分就是在需要发送事件的环境使用post方法来发送事件信息。这三部分中所用到的eventBus实例得要是同一个实例。
@Subscribe 注解介绍
上面的接收事件的方法中,我们提到,必须要加入@Subscriber注解才可以,这其中的因果我们将在下篇文章进行分析,我们现在所要说的是Subscribe注解的用法。
@Subscribe是EventBus自定义的一种注解,他可接收三个参数。ThreadMode、boolean sticky、int priority。
所以上面的接收Event方法的代码,完整版的可以这样写:
这三个参数可以根据需要选择是否使用。
threadMode 是用来决定onReceiveMsg将在哪种线程环境下被调用。EvenBus一共有5种Thread mode。
POSTING :这是EventBus的默认模式,表示post事件是什么线程,onReceiveMsg接收事件方法就在同样的线程环境中执行代码。例如:
订阅处
发布处
结果

我们看到,他们所处的线程环境是一样的。
区别在于,对于MAIN 模式,如果事件发布者post事件也是在主线程的话,会阻塞post事件所在的线程。意思就是连续post多个事件,如果接收事件方法执行完,才能post下一个事件。
post(1) ——> onReceiveMsg(1) ———>post(2)———>onReceiveMsg(2)———>post(3)————>onReceiveMsg(3)
如果事件发布者post事件不在主线程的话,连续post多个事件,同是在主线程是接收事件是耗时操作的话,执行的流程会是这样的。是非阻塞的(non-blocking)
post(1)——>post(2)——>psot(3)———>onReceiveMsg(3)
或者
post(1)——>post(2)——>psot(3)———>onReceiveMsg(2)——>onReceiveMsg(3)
那对于MAIN_ORDERED模式无论事件发布者post在什么线程环境,他的执行流程是都非阻塞的(non-blocking),和MAIN模式 下,post环境不是主线程的执行流程一样。
BACKGROUND:该模式下的时间发布者post线程环境与事件接收onReceiveMsg方法的线程环境关系如下:
post发布环境是主线程的话,事件接收处理的环境是一个子线程。
post发布环境是子线程的话,事件接收处理环境和post发布环境一样。
ASYNC:该模式表示,无论post环境是什么线程,事件接收处理环境都是子线程。
以上就是EventBus五种线程模式的解读。上面说了Subscriber注解的ThreadMode参数的含义。接着我们说另外两种参数的含义。
sticky
我首先会点击触发go事件,通过postSticky()发送一个事件,然后再通过点击触发register事件,对Subscriber进行注册。结果log如下:
priority
该参数是int型,默认值是0,比较好理解,就像他的参数名所表示的那样,优先级。值越高,越先接收到事件,不过这里要注意一个问题,那就是优先级的比较前提是在post事件发布,onReceiveMsg事件接收处理这两方的线程环境相同的前提下,才有意义。同是与priority相配合使用的一个方法是cancelEventDelivery.关于它们的使用就不在演示,比较简单。
EventBus的入门篇,大致就说这些, 可能还有些注意问题,暂时没想起来,等下一篇,关于EventBus源码分析的时候到时候遇到了,再提出来吧。
本文转自EventBus 使用(全面分析,细节提醒)
版权声明:
本文来源网络,所有图片文章版权属于原作者,如有侵权,联系删除。
本文网址:https://www.mushiming.com/mjsbk/13970.html