eventBus源码解析

EventBus定义:是一个发布 / 订阅的事件总线。 发布者,订阅者,事件,总线。

EventBus,可以说,就是在一个单例内部维持着一个map对象存储了一堆的方法;post无非就是根据参数去查找方法,进行反射调用

首先注册

EventBus.getDefault().register(this);//订阅事件

EventBus.getDefault().post(object);//发布事件

EventBus.getDefault().unregister(this);//取消订阅

onEventMainThread() 该方法执行对数据的绑定

如果方法名以onEvent开头,则代表要订阅一个事件,MainThread意思,这个方法最终要在UI线程执行;当事件发布的时候,这个方法就会被执行。

在onCreate里面执行EventBus.getDefault().register(this);意思是让EventBus扫描当前类.把所有onEvent开头的方法记录下来,如何记录呢?使用Map,Key为方法的参数类型,Value中包含我们的方法。

当子线程执行完毕,调用EventBus.getDefault().post(new ItemListEvent(Item.ITEMS))时,EventBus会根据post中实参的类型,去Map中查找对应的方法,于是找到了我们的onEventMainThread,最终调用反射去执行我们的方法。

EventBus的ThreadMode

EventBus包含4个ThreadMode:PostThread,MainThread,BackgroundThread,AsyncThread;

onEventMainThread   代表这个方法会在UI线程执行

onEventPostThread    代表这个方法会在当前发布事件的线程执行

onEventBackgroundThread   这个方法,如果在非UI线程发布的事件,则直接执行,和发布在同一个线程中。如果在UI线程发布的事件,则加入后台任务队列,使用线程池一个接一个调用。

eventBus源码解析_第1张图片

onEventAsyncThread 加入后台任务队列,使用线程池调用,注意没有BackgroundThread中的一个接一个。

eventBus源码解析_第2张图片

本质上调用的同一个

subscriber 是我们扫描类的对象,也就是我们代码中常见的this;

methodName 这个是写死的:“onEvent”,用于确定扫描什么开头的方法,可见我们的类中都是以这个开头。

sticky 这个参数,解释源码的时候解释,暂时不用管

priority 优先级,优先级越高,在调用的时候会越先调用。

调用内部类SubscriberMethodFinder的findSubscriberMethods方法,传入了subscriber 的class,以及methodName,返回一个List。

22行:看到没,clazz.getMethods();去得到所有的方法:

23-62行:就开始遍历每一个方法了,去匹配封装了。

25-29行:分别判断了是否以onEvent开头,是否是public且非static和abstract方法,是否是一个参数。如果都复合,才进入封装的部分。

32-45行:也比较简单,根据方法的后缀,来确定threadMode,threadMode是个枚举类型:就四种情况。

最后在54行:将method, threadMode, eventType传入构造了:new SubscriberMethod(method, threadMode, eventType)。添加到List,最终放回。

eventBus源码解析_第3张图片

扫描了所有的方法,把匹配的方法最终保存在subscriptionsByEventType(Map,key:eventType ; value:CopyOnWriteArrayList)中;

eventType是我们方法参数的Class,Subscription中则保存着subscriber, subscriberMethod(method, threadMode, eventType), priority;包含了执行改方法所需的一切。

regist完毕后,如何post呢?

post方法中有一个PostingThreadState包含了一个eventQueue和一些标志位。

 currentPostingThreadState是一个ThreadLocal类型的,里面存储了PostingThreadState;

post会根据实参去map查找进行反射调用 

你可能感兴趣的:(eventBus源码解析)