EventBus是Android事件发布/订阅框架。
Handler的2种通信
- 主线程发送消息
sendMessage(msg),子线程处理消息handleMessage(msg)。 - 子线程发送消息
sendMessage(msg),主线程处理消息handleMessage(msg)。
EventBus流程
EventBus使用
- 导入依赖
- 定义一个事件Event
- @Subscribe标注订阅者,threadMode = ThreadMode.MAIN 表示
onMessageEvent方法在主线程中运行 - 在
onStart和onStop中注册、解注册事件。注册、解注册尽量和组件(Activity/Fragment)的生命周期绑定 - 发送事件,调用
EventBus.getDefault().post传入自定义的事件
- 发送事件后,所有注册该事件的订阅者都能接收到该事件(msg="Hello everyone!")。
EventBus实现原理
EventBus.getDefault()用来创建EventBus实例- 单例,并使用双重锁校验
- 注意构造函数是public的,一般单例模式下构造函数时private的
- 跟进DEFAULT_BUILDER,发现使用的是Build内部类构建者模式进行对象创建
- EventBus用到ThreadLocal,ThreadLocal可以在指定的线程中存储/获取数据,其他线程无法获取
- 2个HashMap
subscriptionsByEventType: key -event; value -subscriber。当发送事件时,可以由该HashMap根据event找到订阅者。 typesBySubscriber: key -subscriber; value -event。用于注册/解注册事件。 - 3个Poster
- HandlerPoster: extend Handler。不停地从队列中获取PendingPost,通过
eventBus.invokeSubscriber(pendingPost)分发PendingPost。 - BackgroundPoster: extend Runnable。不断从队列中取数据,
eventBus.invokeSubscriber(pendingPost)分发,直到取完为止。 - AsyncPoster: extend Runnable。从队列中获取一个PendingPost,
eventBus.invokeSubscriber(pendingPost)分发。
- 跟进DEFAULT_BUILDER,发现使用的是Build内部类构建者模式进行对象创建
- 单例,并使用双重锁校验
粘性事件
findUsingReflectionInSingle方法流程
- 利用反射查找订阅者订阅的方法
- 遍历所有方法
getModifiers()拿到方法的修饰符,getParameterTypes()拿到方法的参数。由于EventBus只允许订阅方法的订阅事件是一个,则根据一个参数的判断(length == 1)过滤出订阅方法。
getAnnotation(Subscribe.class)过滤出只被@Subscribe修饰过的方法methodName1。
methodName1.threadMode()获取被@Subscribe修饰过的方法的线程模式。
subscribe方法流程
- subscriptionsByEventType是一个HashMap,可以通过它找到订阅者、订阅方法、参数等。
- typesBySubscriber是一个HashMap,可找到该订阅者订阅的所有事件。
checkPostStickyEventToSubscription中会先判断是否是粘性事件,是否考虑继承关系,最后分发事件。
post方法流程
- 通过保存状态的HashMap(subscriptionsByEventType)找到subscription的集合,然后依次遍历,通过
postToSubscription方法完成订阅。
-- 进入postToSubscription- 4个case的判断,不同的case使用不同的Poster(见上)分发。