从以下几个方面来解析:
1、EventBus创建方式有两种:单利和建造者模式。
2、EventBus查找满足条件的订阅方法,有两种方式:反射查找和注解处理器(Annotation Processor)查找。
3、EventBus如何实现订阅的(用观察者模式)。
4、如何取消注册的。
5、EventBus是如何切换线程处理的。
6、sticky事件是如何实现的。
整体思路捋清楚了,那就一步一步来。不了解注解处理器(Annotation Processor)的可以参考哦http://hannesdorfmann.com/annotation-processing/annotationprocessing101
一、EventBus创建方式
单利:全局赋值给defaultInstance
建造者:
通过
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).installDefaultEventBus();
或者
EventBus eventBus = EventBus.builder().addIndex(new MyEventBusIndex()).build();获取,有什么区别呢?
可以看到使用 installDefaultEventBus 中会判断是否已经通过单利获取过EventBus实例并赋值给 EventBus.defaultInstance,
build()是直接创建一个。
二、获取subscribeMethod
Register:
findSubscriberMethods
METHOD.CACHE进行存储,首先是从map中根据subscribe取List<subscriberMethod>,有直接返回,没有就查找。ignoreGeneratedIndex不做处理默认是true(可能你查看,会发现应该是默认false,错,那是jvm在PerfTestEventBus中进行了赋值为true,这个不重要,继续往下),所以会走 findUsingReflection。
findUsingReflection
prepareFindState
initForSubscriber
在prepareFindState中去状态池去拿,没有的话new。这个状态池非常巧妙,后边就会看出来。
initForSubscriber进行了初始化。
findUsingReflectionInSingleClass
SubscribeMethod
findUsingReflectionInSingleClass中可以看出通过反射排除no public ,param lenth不等于1,最后找到带@Subscribe注解的然后获取注解的value装到SubscribeMethod方法中赋值给了findState.subScriberMethod,SubscribeMethod方法中封装这关于subscribe的信息。然后后执行getMethodAndRelease
recycle
这边看到刚才我会把刚才在prepareFindState()中new的FindState转移赋值,并把内置的资源清空但不置空在放到状态池中,得以资源完全复用。秒!然后把subscribeMathods放到METHOD_CACHE中。查找就完毕了。注解器查找在这里https://blog.youkuaiyun.com/wangchao1412/article/details/84635657
三、订阅
Subscription
以上代码可以大致分为三块
1、Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType,存储EventType对应的所有订阅方法。用于post可以执行subscriberMethod。这里先从subscriptionsByEventType取,看182-184行,如果为null直接new一个list赋值subscription去put,在173-179回去遍历subscription根据优先级去插入位置。
2、Map<Object, List<Class<?>>> typesBySubscriber,存储subscriber对应的所有的EventType。
为了方便下边将unregister,先说一下。取消注册就是通过subscriber先拿到typesBySubscriber中对应的List<EventType>,然后再遍历List<EventType>,把EventType作为key从subscriptionsByEventType拿到所有的订阅者,在通过Subscription.subscriber和当前的subscriber对比,如果是同一个,就把Subscription从当前的list中移除。
3、粘性事件处理,看下边postSticky中,直接给stickyEvents中添加了事件,在上变203-204行,会拿到当前要注册的订阅者的时间类型作为key,如果不为null,说明该订阅者就是需要执行粘性事件的,直接checkPostStickyEventToSubscription执行。
四、取消注册unRegister
unregister
五、post是如何切换线程的
post
PostingState
postSingleEventForEventType
postToSubscription
Posting:和post线程一致。
Main:在主线程执行。如果post是在子线程,调用mainThreadPoster(extends handler,lopper is main)发送到主线程invoke执行。否则直接invoke执行。
Background:在子线程同步执行。如果post是子线程调用BackgroundPoster(实现了Runnable接口),将消息存入队列,在run方法中invoke。否则直接invoke。
Async:在子线程中异步执行。如果post是子线程调用BackgroundPoster(实现了Runnable接口),将消息存入队列,在run方法中invoke。否则直接invoke。