EventBus 使用
很早之前就听过 EventBus 这个神器了,因为参与了新项目,维护同事的代码,全部用的是 EventBus,有必要学习一下。Android 原生的广播,实际项目中使用的确实是比较少,除非是一些 ROM 开发。我们是实用主义者,所以就先记录如何使用,然后等会用后再去研究原理。
确保EventBus 已添加到项目依赖。
1. 定义Event
Event 没有特殊要求,就是普通的 Java 对象。例如下面的代码,如果不需要传值,可以只写一个空类。1
2
3
4
5
6public class MessageEvent {
public final String message;
public MessageEvent(String message) {
this.message = message;
}
}
2. Subscriber订阅者
Subscriber 实现 Event 处理,实现的方法在事件被发布的时调用。Subscriber 方法使用 @subscribe 注解定义。
1 | // This method will be called when a MessageEvent is posted (in the UI thread for Toast) |
PS: 对于 EventBus 3,方法名可以自由选择(没有 EventBus 2 中的命名约定)
2.1 注册EventBus
Subscriber 只有在注册后才可以接收到事件。对于 Android ,在 Activity 和 Fragment 中通常应该根据生命周期注册。对于大多数情况,分别在 onStart 和 onStop 注册和反注册就可以,如下代码,也可以根据情况,在 onCreate,或者 onDestroy 中注册和反注册。1
2
3
4
5
6
7
8
9
10
11@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
3. 发布Event
代码中的任意部分都可以发布事件。所有已注册并且匹配该类型的 Subscriber(订阅者)都会收到该事件.1
EventBus.getDefault().post(new MessageEvent("Hello everyone!"));
ThreadMode
EventBus不仅可以处理传递信息,还可以处理线程切换问题。事件可以发布到与发布线程不同的线程中。
对于 Android,UI 改变必须发生在 UI(main)线程中。另一方面,网络请求或其他任何耗时的任务不得在主线程上运行。EventBus 可以处理这些问题,并与 UI 线程保持协调。
主要有以下四种线程模式1
2
3
4
5ThreadMode:POSTING(默认)
ThreadMode:MAIN
ThreadMode:MAIN_ORDERED
ThreadMode:BACKGROUND
ThreadMode:ASYNC
查看了官方的英文文档,MAIN 与 MAIN_ORDERED 模式,Subscriber 都是运行在主线程的,区别是 MAIN_ORDERED 保证了事件处理有一个更严格一致的顺序。
比如,在 MAIN 模式下,处理事件的时候发布另一个事件,则第二个事件将先于第一个事件被处理完成(此处为同步调用,可与方法调用类比)。而对于 MAIN_ORDERED,第一个事件将先被完成处理,然后第二个事件在稍后的时间点(一旦主线程有处理能力时)被处理。
BACKGROUND 事件回调将在后台线程中被调用。如果发布事件的线程不是主线程,事件回调将直接在发布线程被调用。否则,EventBus 使用一个后台线程(单例)来按序调用每个回调
ASYNC 事件回调方法总是在单独的线程被调用。这些线程不会是发布事件的线程,也不会是主线程。