一 概述
EventBus 是适用于 Android 和 Java 的发布/订阅事件总线。主要功能是替代 Intent、Handler、BroadCast 在 Activity、Fragment、Service 线程之间传递消息。EventBus 能够简化应用组件间的通信,解耦 (有效分离) 事件的发送者和接收者,避免复杂和容易出错的依赖和生命周期问题,开销小,代码更优雅。但是需要注意的是 EventBus 不能用于进程间通信。
Andorid 组件间通信,可能都是用 Handler 消息机制或者广播机制来实现通信,但是它们代码量大,组件上容易产生耦合 。为什么选择使用 EventBus 来做通信?
- 简化了组件间的通信
- 对事件通信双方进行解耦
- 在 Activity、Fragment 和后台线程中能很好使用
- 避免了复杂且容易出错的依赖性和生命周期问题
- 可以灵活方便指定工作线程和优先级
- 速度快,性能好,代码简单优雅
- 库比较小,不占内存
二 使用步骤
1.定义事件对象
事件对象可以是任意 java 类型,没有特殊要求,比如 String、int、自定义类等。
public class MessageEvent {
public String name;
}
2.在接收消息的页面注册事件
EventBus.getDefault().register(this);
- register(Object subscriber):EventBus 订阅事件的方法,通过 EventBus.getDefault() 获取事件总线实例;参数 subscriber 为订阅者,订阅者有处理事件的方法,并且必须添加 @Subscribe 注解。
只有注册了订阅事件,才会接收到消息。注意:通常根据 Activity 和 Fragment 的生命周期注册和注销事件。
3.订阅者实现事件处理方法
也称为"订阅者方法",当发布对应事件类型时,该方法被调用(在接收消息的页面)。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent message){
//TODO 接收事件后Do something
}
- @Subscribe: 必须使用 @Subscribe 注解来定义订阅者方法,否则事件处理方法无法生效。
- threadMode: 线程模式,表示在哪个线程里面执行,ThreadMode.MAIN 表示在主线程执行该方法。(其他模式在下一篇讲解)
- onMessageEvent(MessageEvent message): 事件处理方法的方法名称,onMessageEvent() 是任意的合法方法名,开发者可以自己定义;参数类型 MessageEvent 为定义接收事件的对象类型,要与发布事件的类型一致,否则无法接收事件。
4.发布事件
EventBus.getDefault().post(Object event);
- post(Object event): EventBus 发送事件的方法,参数 event 为事件对象,是 Object 任意类型,这里发送的类型需要与接收事件的类型一致。当前与事件类型匹配的所有已注册的事件都会接收到。
5.在接收消息的页面注销 (解除注册) 事件
EventBus.getDefault().unregister(this);
- unregister(Object subscriber): 订阅者注销事件的方法,如果事件不需要使用了必须调用该方法注销事件。当消息页面不存在或者不需要事件了注销该事件。
三、项目实战
3.1 普通使用
我们首先来演示个例子,在 OneActivity 中注册事件并实现事件处理方法,点击按钮跳转到 TwoActivity 中,点击 TwoActivity 的“发送事件”按钮向 OneActivity 发送事件,OneActivity 在接收到事件信息后,发送一个 Toast 并将接收的数据显示在屏幕上。
我们按照下面的步骤实现这个效果:
1.使用 EventBus 需要在 build.gradle 文件中添加依赖:
添加 EventBus3.2 依赖:
implementation 'org.greenrobot:eventbus:3.2.0'
2.定义事件对象
事件对象可以是任意 java 类型,比如 String、int、自定义类等,没有特殊要求,开发者可以根据需求选择。这里我们定义一个类 MessageEvent:
public class MessageEvent {
public MessageEvent(String name) {
this.name = name;
}
public String name;
}
这个类很简单,只定义了一个参数 name,构造时传入一个字符串。它是用于我们发送事件的事件对象携带参数的封装类,在下面订阅者方法接收的参数中也是以 MessageEvent 为接收类型才能接收到。两个类型要一致才能成功接收到发出的数据。
3.在接收消息的页面注册和注销事件
从上面的效果可以看到在 OneActivity 中接收到事件消息,那么我们需要在 OneActivity 注册和注销事件,通常根据 Activity 和 Fragment 的生命周期注册和注销事件。那么我们在 Activity 的 onCreate() 方法中注册事件,在 onDestroy() 方法中注销事件:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault().register(this);
}
@Override
protec