EventBus实现原理
EventBus主要是在项目运行时通过反射来查找订阅事件的方法信息,如果项目中有大量的订阅事件的方法,必然会对项目运行时的性能产生影响。其实除了在项目运行时通过反射查找订阅事件的方法信息,EventBus还提供了在项目编译时通过注解处理器查找订阅事件方法信息的方式,生成一个辅助的索引类来保存这些信息
Subscribe注解
-
EventBus从3.0开始使用Subscribe注解配置事件订阅方法,不再使用方法名,注解中有三个方法
-
ThreadMode threadMode() default ThreadMode.POSTING;
- 指定事件订阅方法的线程模式,即在那个线程执行事件订阅方法处理事件,默认为POSTING
-
boolean sticky() default false;
- 是否支持粘性事件,默认为false
-
int priority() default 0;
- 指定事件订阅方法的优先级,默认为0,如果多个事件订阅方法可以接收相同事件的,则优先级高的先接收到事件
-
EventBus.getDefault.register()注册
-
getDefault是一个单例方法,保证当前只有一个EvenBus实例,最终调用new Eventbus()
-
register()分为查找和注册两部分,主要通过findSubscriberMethods()方法从缓存中查找订阅的事件的集合,如果找到则直接返回,否则去做下一步的查找过程,然后缓存查找到的集合,然后通过reigister中的subscirbe()方法进行注册
-
方法主要是得到了subscriptionsByEventType、typesBySubscriber两个HashMap。其中,发送事件的时候要用到subscriptionsByEventType,完成事件的处理
-
当取消EventBus注册的时候要用到typesBySubscriber、subscriptionsByEventType,完成相关资源的释放
EventBus.getDefault().unregister(this);取消注册
- 在unregister()方法中,最主要的就是释放typesBySubscriber、subscriptionsByEventType中缓存的资源
EventBus.getDefault().post("Hello World!")事件的发送
-
post()方法先将发送的事件保存到List的事件队列,然后通过循环出队列,将事件交给postSingleEvent()方法处理
-
方法核心就是遍历发送的事件类型对应的Subscription集合,然后调用postToSubscription()方法处理事件,postToSubscription()内部会根据订阅事件方法的线程模式,间接或直接的以发送的事件为参数,通过反射执行订阅事件的方法
![](https://img.haomeiwen.com/i18571330/dcc52cfa0c84bfdc.png)