Android事件总线之EventBus

Android事件总线之EventBus

八归少年 2,206 2020-01-08

首语

  • 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)//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();//移除所有的粘性事件

总结

  • 优点:简化组件之间的通信方式,实现解耦让业务代码更加简洁,可以动态设置事件处理线程以及优先级。
  • 缺点:目前发现唯一的缺点就是类似之前策略模式一样的诟病,每个事件都必须自定义一个事件类,造成事件类太多,无形中加大了维护成本。

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.yanghujun.com/archives/eventbus