事件总线EventBus
介绍
三要素
- Event:事件,可以是任意类型的对象
- Subscriber:事件订阅者,在EventBus3.0之前消息处理的方法只能限定OnEvent,onEventMainThread,onEventbackgroundThread和onEventAsync,他们分别代表四种线程模型,在3.0之后,事件处理的方法可以随便取名,但是需要添加一个注解@Subscriber,并且要指定县城模型(默认为POSTING),4种线程模型下面会讲
- Publisher:事件发布者,可以在任意线程任意位置发送事件,直接调用EventBus的post(Object)方法,可以自己实例化EventBus对象,但一般使用EventBus.getDefault()就可以,根据post函数参数的类型,会自动调用订阅相应类型事件的函数
EventBus的四种ThreadMode
- POSTING(默认):事件处理函数会在发布该事件的线程中执行,也就是说事件发布和处理是在一个线程当中的,这种的话应该尽量避免执行耗时操作,因为他会阻塞事件的传递
- MAIN:事件的处理会在UI线程当中执行,所以这个处理的时间不能太长
- BACKGROUND:如果事件是在UI线程发出的,那么该事件的处理就会在一个新线程中运行,如果不是在UI线程,那么事件的处理直接在当前线程执行,此类事件处理函数应避免执行UI操作
- ASYNC:事件处理函数总会在新线程执行,此类处理函数也应该避免进行UI操作
使用
使用前
compile 'org.greenrobot:eventbus:3.1.1'
基本用法
public class MyEvent {
private String message;
public MyEvent(String message){
this.message = message;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}
- 在需要的地方(比如说在MainActivity)注册事件
EventBus eventBus = EventBus.getDefault()
eventBus.register(MainActivity.this)
EventBus eventBus = EventBus.getDefault()
eventBus.post(new MyEvent("我是消息"))
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMoonEvent(MyEvent event){
tv_message.setText(event.getMessage());
}
- 这里要说明的是事件处理的方法用了注解,表示这个事件的线程模型
- 最后不要忘记将事件在合适的事件取消注册(比如在MainActivity的onDestory的方法中)
EventBus.getDefault().unregister(MainActivity.class)
基本分析
- 简单的分析一下我们就可以发现
- 事件总线其实就相当于广播一样,其中的重点在于事件这个类,这个类可以包括一些我们想要去传递的参数
- 然后,哪里需要去接收这个类的实例,就在哪里注册一下事件,表明,我要这个类型的事件(所谓事件也就是刚才我们定义的事件类)
- 外部在合适的时机,事件
- 然后,在合适的时候,我们发现,我们不需要这个事件了,就需要取消注册,表明,我不需要这个类型的事件了
用法进阶(粘性事件)
- 这个事件的说明是,当我们先发出事件,然后再去订阅,还是同样可以接收到事件的,不过我们需要在事件处理的注解中声明粘性事件为true,比如
@Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
public void onMoonEvent(MyEvent event){
tv_message.setText(event.getMessage());
}
eventBus.postSticky(new MyEvent("00000000000000"));
- 不注册,直接发送粘性事件,则在注册后只能由粘性事件接收器接收
- 先注册事件,那么就不管是什么事件都接收
- 代码在git
再来看一下Otto
- 基本用法没什么区别
- 建事件类
- 在合适的地方注册并接收
@Subscribe
public void setContent(OttoMessage message){
tv_message.setText(message.getMessage());
}
不同点,他有一个注解@Produce
- 在来到有这个注解的类中必须立即订阅,并且在生产完成事件后必须取消订阅
- 在这中间这个注解方法起作用,发送事件
@Produce
public OttoMessage lalalala(){
return new OttoMessage("我是消息");
}
- 大概就这样,因为这个Otto已经不在更新,推荐使用RxJava或者RxAndroid来替代他