带你一步步参透EventBus源码

从以下几个方面来解析:

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.csdn.net/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。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值