EventBus使用详解

EventBus 介绍

EventBus 是一个用于组件间通信的框架。它为开发提供一种非常简便的方式来是实现组件间解耦通信,并且提供了线程切换、优先级设置等功能。

EventBus 使用的是观察者模式: Subscriber 注册到 EventBus , 当 Publisher 使用 post 方法将 Event 发送给 EventBusEventBus 就会回调 SubscriberonEvent 方法。观察者模式能将观察者和订阅者最大程度的解耦,这也是 EventBus 的功能所在。

EventBus 使用(反射模式)

第一步:添加依赖。

implementation 'org.greenrobot:eventbus:3.1.1'

第二步:新建要通讯的各种事件。

// 测试事件
public class TestEvent {
}

// 测试继承事件
public class SonTestEvent extends TestEvent {
}

第三步:注册和反注册订阅者。

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mEventBus = EventBus.getDefault();
    mEventBus.register(this);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mEventBus.unregister(this);
}

第四步:创建订阅方法。

@Subscribe(threadMode = ThreadMode.MAIN)
@Override
public void testEvent2(TestEvent event) {
    Toast.makeText(this, "testEvent2", Toast.LENGTH_SHORT).show();
}

第五步:发送相应事件。

mEventBus.post(new TestEvent());

注意事项: 订阅方法不能是静态的、私有的,订阅参数只能有一个而只能是引用类型的,不能是基础类型(比如 int ,float)。

粘性事件

在注册订阅者的时候,会立即回调订阅方法的事件,需要将方法设置为粘性方法,发送事件时用 postSticky 即可。

@Subscribe(sticky = true)
public void testSticky(TestEvent testEvent) {
    mSticky.setText("mSticky");
}

EventBus.getDefault().postSticky(new SonTestEvent());

注意:只要发送过粘性事件,当调用注册订阅者 (register) 方法时,都会回调订阅方法。

@Subscribe 注解

/**
 * threadMode 
 * 表示方法在什么线程执行 (Android更新UI只能在主线程, 所以如果需要操作UI, 需要设置ThreadMode.MainThread)
 * 
 * sticky     
 * 表示是否是一个粘性事件 (如果你使用postSticky发送一个事件,那么需要设置为true才能接受到事件)
 * 
 * priority   
 * 优先级 (如果有多个对象同时订阅了相同的事件, 那么优先级越高,会优先被调用.)
 * */
@Subscribe(threadMode = ThreadMode.MainThread, sticky = true, priority = 100)
public void onEvent(MsgEvent event){
}

通过APT技术生成索引文件方式

第一步:添加依赖并配置参数。

annotationProcessor 'org.greenrobot:eventbus-annotation-processor:3.1.0'

defaultConfig {
    javaCompileOptions {
        // 注解处理器参数配置
        annotationProcessorOptions {
            // 配置参数名和值
            arguments = [ eventBusIndex : 'zeng.fanda.com.eventbusdemo.MyEventBusIndex' ]
        }
    }
}

第二步:重新编译便可生成 MyEventBusIndex 索引类,调用如下代码把索引类添加到默认的 EventBus 配置:

EventBus.builder().ignoreGeneratedIndex(false).
            addIndex(new MyEventBusIndex()).installDefaultEventBus();

通过以上两步设置后,EventBus 内部就会用索引文件的方式去查找订阅方法,避免了反射的性能消耗。