前文
由于EventBus的源码还是比较的复杂的,打算使用五篇文章从浅入深的分析它的源码。包括:
- post流程的分析【本文】
- register流程分析(反射方式)
- register流程分析(注解方式)
- stickey消息实现和处理
- 最佳实践
阅读文章的前提需要有java反射的知识+实践过EventBus
,本文的阅读还需要有ThreadLocal
基础,源码分析基于EventBus的3.3.1
版本。
EventBus的原理图如下:
引入和使用
具体可以参考Eventbus的Github或者是官方接口文档
简单例子入手
1 | //发送消息 |
- 我们通过
EventBus.getDefault().post(obj)
发送消息 - 我们通过
EventBus.getDefault().register(obj)
来在页面中进行注册和EventBus.getDefault().unregister(obj)
反注册,从而使得页面可以接收消息, - 我们通过
@Subscribe
注解去某一个方发处理消息,该方法的参数是post(obj)
的对象的Class类型
关于他们的具体细节我们后续再细说,我们先引出这几个关键的类并尝试看看他们的基本作用。
Post流程分析
ThreadLocal
由于在Eventbus中使用到了ThreadLocal,关于ThreadLocal类的解析,可以看ThreadLocal的实现原理,简单的来说就是他可以保存每个线程自己单独拥有数据。
post方法
大体的流程图
主要流程是:post
->postSingleEvent
->postSingleEventForEventType
->postToSubscription
下面是源码,我们来逐行解析
1 | public void post(Object event) { |
首先currentPostingThreadState
是一个ThreadLocal对象,也就是通过他得到的是专属于当前调用线程的postingState
对象,每个线程的postingState
都是独立的(后续再详说下使用它避免的问题和优点),然后我们分析下PostingThreadState
类,
1 | final static class PostingThreadState { |
通过post
方法,得到需要派发的PostingThreadState
对象,然后轮循调用postSingleEvent
方法进行派发
1 | private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { |
postSingleEvent
方法也比较的简单,这里就不多说了,他就获取event
的class,然后就调用postSingleEventForEventType
,通过class来定位到是那些Subscription
订阅了该event
1 | private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { |
这里看上面的注释也基本明白了,postSingleEventForEventType
的作用是寻找订阅了event的Subscription,然后通过postToSubscription
实现最终的分发,在介绍之前,我们先看下ThreadMode
类,他是每个Subscription(观察者)接收event的时候使用的线程模式,有五种类型
1 | POSTING,在当前调用post()方法的线程执行 |
1 | private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { |
invokeSubscriber方法就是通过反射的方式,调用Subscription中的method,把event传递给该event
1 | void invokeSubscriber(Subscription subscription, Object event) { |
自此,我们的post流程走完,虽然还有一些问题,但是大体上我们是理得清的,再回顾下就是:
- 通过post方法发送event,得到需要发送的消息队列(为何是队列?因为我们的订阅方法中可以继续发起新的事件post),然后轮循该消息队列,把消息传递给
postSingleEvent
- 通过
postSingleEvent
,拿到可以接受event的class,就是方法的参数是可以接收event的类有那些,然后就轮循所有的class,查询了订阅了该class的Subscription,调用postSingleEventForEventType
- 通过
postSingleEventForEventType
,得到具体class的所有Subscription
,然后就调用postToSubscription
方法进行分发 - 通过
postToSubscription()
方法,给具体的Subscription
基于他自己的ThreadModel通过反射的方式进行事件分发