首语
- EventBus是一个Android端优化的publish/subscribe消息总线,简化了应用程序内各组件间、组件与后台线程间的通信。比如请求网络,等网络返回时通过Handler或Broadcast通知UI,两个Fragment之间需要通过Listener通信,这些需求都可以通过EventBus实现。实现解耦让业务代码更加简洁,可以动态设置事件处理线程及优先级。
原理框图
三要素
- Event——事件。他可以是任意类型。
- Subscriber——事件订阅者。EventBus3.0之前必须定义OnEvent开头的那几个方法,分别是onEvent、onEventMainThread、onEventBackgroundThread、onEventAsync,在3.0以后,事件处理的方法名可以随意取,不过需要加上注解@Subscribe(),并且指定线程模型,默认是POSTING。
- Pusblisher——事件的发布者。可以在任意线程里发布事件,一般情况下,使用EventBus.getDefault()就可以得到一个EventBus对象,然后再调用post(Object)方法即可。
四种线程模型
- PostThread(默认)表示事件处理函数的线程跟发布事件的线程在同一个线程。
- MainThread表示事件处理函数的线程在主(UI)线程,因此不能进行耗时操作。
- BackgroundThread表示事件处理函数的线程在后台线程,因此不能进行UI操作,如果发布事件的线程是主(UI)线程,那么事件处理函数将开启一个后台线程。如果发布事件的线程是在后台线程,那么时间处理函数就使用该线程。
- Async表示无论事件发布的线程在哪一个,事件处理函数始终会新建一个子线程运行,同样,不可以进行UI操作。
GitHub地址:https://github.com/greenrobot/EventBus
官方文档:http://greenrobot.org/eventbus/documentation
依赖:implementation 'org.greenrobot:eventbus:3.1.1'
基本用法
1.注册事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EventBus.getDefault().register(this);
}
2.解除注册
@Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
}
3.构造发送事件类
public class MessageEvent {
public String name;
public String password;
public MessageEvent(String name, String password) {
this.name = name;
this.password = password;
}
}
4.发送事件
EventBus.getDefault().post(new MessageEvent("dahaige","123456"));
5.处理事件
@Subscribe(threadMode = ThreadMode.MainThread)
public void MessageEventBus(MessageEvent event){
tvData.setText(event.name);
tvTitle.setText(event.password);
}
终止事件向下传递
EventBus.getDefault().cancelEventDelivery(event);
粘性事件
- 粘性事件是指在EventBus内部被缓存的那些事件,发送事件之后再订阅该事件也能收到该事件。与普通事件的区别是普通事件先注册后绑定,才能接受到事件。粘性事件先发送事件,不需要先注册,也能接收事件。
1.构造发送事件类
public class StickyEvent {
public String msg;
public StickyEvent(String msg) {
this.msg = msg;
}
}
2. 发送粘性事件
EventBus.getDefault().postSticky(new StickyEvent("我是粘性事件"));
3.处理粘性事件
@Subscribe(threadMode = ThreadMode.MainThread,sticky = true)
public void StickyEventBus(StickyEvent event){
tvResult.setText(event.msg);
}
4.注册事件
EventBus.getDefault().register(CActivity.this);
5.解注册
EventBus.getDefault().removeStickyEvent(new StickyEvent(tvResult.getText().toString()));
EventBus.getDefault().removeAllStickyEvents();
总结
- 优点:简化组件之间的通信方式,实现解耦让业务代码更加简洁,可以动态设置事件处理线程以及优先级。
- 缺点:目前发现唯一的缺点就是类似之前策略模式一样的诟病,每个事件都必须自定义一个事件类,造成事件类太多,无形中加大了维护成本。