EventBus简介
EventBus是一个Android事件发布/订阅的框架。主要用来在应用程序内各组件间、组件与后台线程间的通信。
比如网络请求数据返回时原来可以通过Handler或者是Broadcast通知ui,fragment之间的需要添加方法和listener进行回调通信。这些需求都可以通过eventbus来实现、
Eventbus的三要素
1、Event:事件,可以自定义为任意类型的对象
2、subscriber“事件订阅者,也就是接收事件的人,在3.0之前消息处理的方法只能限定于OnEvent、onEventMainThread、onEventBackgroundThread和onEventAsync这四个方法,是指定方法名的,也分别代表了四种线程模型。在3.0以后,事件处理的方法名就可以自定义了,但是需要添加注解@Subscribe,并且指定线程模型,默认为posting
3、publisher:事件发布者,可以在任意线程任意位置中发送事件,直接调用post方法,可以自己实例化EventBus对象,但是一般使用EventBus.getDefault()获取对象就好了,根据post方法的参数类型,会自动调用已经注册的订阅响应类型事件的函数
EventBus的四种线程模型(threadMode)
POSTING:默认模型,如果时间处理方法指定了线程模型为POSTING,那么该事件在哪个线程发出来的事件处理方法就在哪个线程中运行,也就是发布事件和事件接受处理在同一个线程中。在此模型中的处理方法中要避免执行耗时操作,可能会阻塞事件的传递,甚至可能会引起ANR
MAIN:事件的处理会在主线程也就是UI线程处理,避免执行耗时操作,会引起ANR
BACKGROUND:后台线程也就是子线程处理,如果事件是在UI线程中发出来的则会开启新的线程来处理,如果本身就是在子线程中发出来的,则在当前子线程进行处理,此模型的事件处理方法中禁止进行UI操作。
ASYNC:无论事件在哪个线程发布,该事件处理函数都会在新建的子线程中执行,同样,此事件处理函数中禁止进行UI更新操作。
使用方法
1、添加引用依赖库
implementation 'org.greenrobot:eventbus:3.0.0'
2、在需要进行接收事件的对象注册
EventBus.getDefault.regist(this)
3、创建消息发送对象
public class EventUser {
public static final int EVENT_LOGIN_SUCCESS = 0;
public static final int EVENT_LOGIN_OUT = 1;
private int action;
private Object data;
public EventUser(int action) {
this.action = action;
}
public EventUser(int action, Object data) {
this.action = action;
this.data = data;
}
public int getAction() {
return action;
}
public void setAction(int action) {
this.action = action;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
4、发布消息
Event.getDefault().post(new EventUser(EventUser.EVENT_LOGIN_SUCCESS));
5、接收消息
@Subscribe(threadMode = ThreadMode.MAIN)
public void userEventBus(EventUser userEvent){
}
6、解注册 防止内存泄露
EventBus.getDefault().unRegist(this);
粘性事件
之前说的使用方法,都是需要先注册(register),再post,才能接受到事件;如果你使用postSticky发送事件,那么可以不需要先注册,也能接受到事件,也就是一个延迟注册的过程。 普通的事件我们通过post发送给EventBus,发送过后之后当前已经订阅过的方法可以收到。但是如果有些事件需要所有订阅了该事件的方法都能执行呢?例如一个Activity,要求它管理的所有Fragment都能执行某一个事件,但是当前我只初始化了3个Fragment,如果这时候通过post发送了事件,那么当前的3个Fragment当然能收到。但是这个时候又初始化了2个Fragment,那么我必须重新发送事件,这两个Fragment才能执行到订阅方法。 粘性事件就是为了解决这个问题,通过 postSticky 发送粘性事件,这个事件不会只被消费一次就消失,而是一直存在系统中,直到被 removeStickyEvent 删除掉。那么只要订阅了该粘性事件的所有方法,只要被register 的时候,就会被检测到,并且执行。订阅的方法需要添加 sticky = true 属性。
网友评论