绿巨人的两个知名开源库EventBus 和GreenDao用了多年,今天闲暇总结下EventBus。
1 Why
官网给出解释
EventBus...
- simplifies the communication between components
- decouples event senders and receivers
- performs well with Activities, Fragments, and background threads
- avoids complex and error-prone dependencies and life cycle issues
- makes your code simpler
- is fast
- is tiny (~60k jar)
- is proven in practice by apps with 1,000,000,000+ installs
- has advanced features like delivery threads, subscriber priorities, etc.
补充下特性:支持事件优先级和继承。
Event Bus 原理基于观察者模式,事件回调处理函数设置2.0和3.0有很大不同,2.0是基于反射机制,3.0可以用注解处理器。
2 How
2.1 2.0的使用
三部曲:
- 定义事件
- 注册及注销
- 发送事件
定义事件
public static class MessageEvent{
}
注册及注销
@Subscribe(threadMode = ThreadMode.MAIN) public void onMessageEvent(MessageEvent event) {/* Do something */};
@Override public void onStart() { super.onStart(); EventBus.getDefault().register(this); } @Override public void onStop() { super.onStop(); EventBus.getDefault().unregister(this); }
发送事件
EventBus.getDefault().post(new MessageEvent());
2.2 Subscriber Index方式
优势:
相对于反射方式占用运行时查找订阅者,index方式是在编译期间完成的。
使用方式:
android {
defaultConfig {
javaCompileOptions {
annotationProcessorOptions {
arguments = [ eventBusIndex : 'com.example.myapp.MyEventBusIndex' ]
}
}
}
}
dependencies {
def eventbus_version = '3.2.0'
implementation "org.greenrobot:eventbus:$eventbus_version"
annotationProcessor "org.greenrobot:eventbus-annotation-processor:$eventbus_version"
}
注解处理器会生成'com.example.myapp.MyEventBusIndex
EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
// Now the default instance uses the given index. Use it like this:
EventBus eventBus = EventBus.getDefault();
发送和注册用法同2.1
3 核心类
3.1 类图
核心类:Subscribe、EventBus、SubscriberInfoIndexes、SubscriberMethodFinder、Subscription等。
3.2 代码分析
1 EventBus
EventBus 是单例模式和Builder模式的类。
EventBus.getDefault()
默认调用采用默认实现:
public static EventBus getDefault() {
EventBus instance = defaultInstance;
if (instance == null) {
synchronized (EventBus.class) {
instance = EventBus.defaultInstance;
if (instance == null) {
instance = EventBus.defaultInstance = new EventBus();
}
}
}
return instance;
}
2 Subscribe
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
ThreadMode threadMode() default ThreadMode.POSTING;
/**
* If true, delivers the most recent sticky event (posted with
* {@link EventBus#postSticky(Object)}) to this subscriber (if event available).
*/
boolean sticky() default false;
/** Subscriber priority to influence the order of event delivery.
* Within the same delivery thread ({@link ThreadMode}), higher priority subscribers will receive events before
* others with a lower priority. The default priority is 0. Note: the priority does *NOT* affect the order of
* delivery among subscribers with different {@link ThreadMode}s! */
int priority() default 0;
}
这个注解应用3个参数,第一个指定事件回调处理的线程,第二个是粘性事件(需要用postSticky,会缓存并发给事件注册晚的监听),第三个事件的优先级。
ThreadMode 有五种类型,主线程只有安卓支持,为此EventBus加入线程池。
Subscribe在2.0和3.0同样起作用,只有被注册的类注解处理器才会生成需要的SubscriberInfoIndexes。
3 注解处理类
org.greenrobot.eventbus.annotationprocesso.EventBusAnnotationProcessor
4 总结
EventBus用于线程间通讯,基于观察者模式,解耦事件的发送和处理,使用起来简单,3.0又用注解做了优化,效率有很大提升。