整体思路
一个最简化的订阅,注册,发布事件
发了一个事件
,如何回调相关注册的方法呢?
最重要的Map,subscriptionsByEventType
,一个事件
对应多个订阅
,订阅
包含了订阅者
和订阅方法
。
一个订阅
包含两个信息,谁去做(订阅者),做什么(交给用户实现的部分),怎么做(线程如何调度,threadMode)
1 |
|
关于注销订阅
订阅建立后,订阅者
接受相关的事件
的订阅就会被触发,做该做的事了,可若是订阅者不想订阅了,不想继续受到该之前订阅的事件了。(或者,生命周期结束了,若不注销订阅,EventBus实例会保留对该订阅者的引用,所以要注销该订阅者的所有订阅)
是的,一个订阅者可以拥有多个订阅,所以,为了注销该订阅者,还得引入
1 |
|
优化
编译时注解处理器生成索引
通过生成索引,EventBus可加快注册的速度,这在Android中是一个很好的优化,毕竟在onCreate方法中耗时太久会导致卡顿。
索引内部使用流程
注册时,需要生成subscriptionsByEventType
,对应一个订阅者,即找到一个
List
而寻找时
1 | if (ignoreGeneratedIndex) { |
可以看到有一个变量,ignoreGeneratedIndex
是否忽视生成索引,默认情况为false,即会尝试从索引查找的。
(在这里,若是没有配置生成索引,其实在配置时设置忽略索引,避免多走一些不必要的路)
而进入findUsingInfo()
1 | private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) { |
而findState中的subscriberInfo是什么呢?
1 |
|
可以看到,这个类定义了EventBus对于一个订阅者,它关注什么信息
注意,文档中说明,对于索引使用是有条件的,如下
Index Preconditions
Note that only @Subscriber methods can be indexed for which the subscriber AND event class are public. Also, due to technical limitations of Java’s annotation processing itself, @Subscribe annotations are not recognized inside of anonymous classes.
When EventBus cannot use an index, it will automatically fallback to reflection at run time. Thus it will still work, just a bit slower.
- 订阅者和事件的类必须是public
- 在匿名类中的@Subscriber标记的方法,注解处理器无法识别
- 故,当使用索引失败时,会倒退到使用发射
忽视事继承性
即事件B继承A,若是订阅了事件A,发送事件B,是可以接收到的。
eventInheritance默认是为true的,支持事件的继承性。
1 | //发布一个事件 |
若是在项目中不会用到事件类型的继承性,也能省不少
比如,事件类型类为String.class,会迭代5次
1 | eventTypes = {ArrayList@908} size = 5 |