一、背景
常用的实现组件间通信的方式有:设置监听器、使用本地广播。设置监听器的弊端在于需要定义业务接口,并且会使监听者与被监听者耦合。使用本地广播的弊端在于广播接收器的回调是在UI线程的,如果想要在其他线程执行操作,需要手动进行切换。
二、概念
三、使用方法
EventBus的使用包括3个步骤:事件的定义、订阅者订阅事件、发布者发布事件。
引入依赖:
implementation 'org.greenrobot:eventbus:3.1.1'
注册EventBus与解除注册代码示例如下:
public class EventBusTestActivity extends AppCompatActivity {
@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
protected void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
}
订阅者处理事件的方法加上@Subscribe注解:
@Subscribe
public void onTestEvent(TestEvent testEvent) {
//do some thing
}
发布者发送事件:
EventBus.getDefault().post(new TestEvent());
四、线程模式ThreadMode
在@Subscribe注解后加括号指明线程模式,如:
@Subscribe(threadMode = ThreadMode.POSTING)
public void onPostingFunc(TestEvent event) {
//do some thing
}
共有5中线程模式,默认为POSTING模式:
1、POSTING:订阅者处理事件的方法与发布者发布事件的代码运行在同一线程。
2、MAIN:保证订阅者处理事件的方法运行于主线程。订阅者处理事件的方法将会阻塞发布者发布事件后后续的代码。即订阅者会被发布者阻塞。
3、MAIN_ORDERED:保证订阅者处理事件的方法运行于主线程。发布者后续代码的执行不受前一次事件发布的影响,不需要等待订阅者将前一次的事件处理完。即订阅者不会被发布者阻塞。
4、BACKGROUND:保证订阅者处理事件的方法运行与非UI线程,如果发布者发布事件的代码运行于非UI线程,则订阅者处理事件的代码运行于同一线程,如果发布者发布事件的代码运行于UI线程,则EventBus将新起一个线程用于执行订阅者处理事件的方法。
5、ASYNC:保证订阅者处理事件的方法运行于一个新的线程(非UI线程,且不是发布者发布事件的线程)。可以放心做耗时操作。
五、粘性事件
普通的使用EventBus的流程为:定义事件、订阅事件、发布事件,而使用粘性事件,可以实现先发布事件,后订阅事件。
发布粘性事件需要使用postSticky进行发布:
EventBus.getDefault().postSticky(new TestEvent());
原理:发布粘性事件时EventBus将事件缓存。
六、开发中的坑记录
1、gradle文件中可以配置属性,在打包apk时将无用的方法删除,由于EventBus的订阅者处理事件的方法是通过反射调用的,可能被编译器认为该方法未使用过而被删除,在混淆文件中配置即可。