EventBus 原理浅析

EventBus是基于方法注解和观察者模式实现的。

EventBus 实现消息通信过程包括三个部分:

register(注册)、post(发送消息)和unregister(注销)

1.register,注册是将订阅者与其感兴趣的事件进行关联的过程。

通过调用EventBus的register()方法实现,register方法主要做了三件事:

(1)通过反射的方式查找suscriber中所有接收事件的方法获取对应的Method对象,解析Method对象的注解信息,并根据这些信息生成一个SubscriberMethod对象,让后将其放入subscriberMethods的集合中。得到这个SubscriberMethod的集合后,EventBus会遍历SubscriberMethod集合,根据SubscriberMethod及所属subscriber生成一个Subscription对象,然后将subscription按照method中的eventType进行分类并按method注解中指定的优先级的顺序保存在不同的list集合中,最后将持有subscription的集合缓存到一个全局的subscribptionsByEventType的map表中,方便后续通过EventType查找到对应的subscriptions集合。

(2)EventBus将subscriber中所有的事件的Class对象保存在一个list集合中,并以subscriber为key,事件的Class集合为value保存到一个全局typesBySubscriber的map表中,方便后续通过subscriber查找到它里面所有的事件类型。

(3)判断当前subscriberMethod对象接收的消息类型是否是sticky(粘性事件)类型的。如果是sticky类型,则判断是需要继续查找该事件类型的子类型事件,默认情况下是需要查找子类型事件的,然后将subscriberMethod所接收的事件类型及所有子类型事件依次发送给当前的subscriberMethod对象。这是register()方法主要做的事情。

2.post,发送消息的过程。

EventBus的post()方法以一个事件对象(可以是系统中类型也可以是自定义的类型)作为参数,将给定事件发送给事件总线。

post()方法主要做了三件事:
(1)通过ThreadLocal获取与当前线程关联的PostingThreadState类对象,然后将待发送事件加入postingState变量的eventQueue队列中。

(2)遍历eventQueue队列中的事件,根据事件的Class对象查找所有的eventTypes,通过eventInheritance标志判断是否需要查找子类型事件,默认情况下是需要查找的。然后遍历eventTypes集合,将集合中事件发送给对应的Subscription对象。

(3)根据eventType查找对应的subscriptions集合,然后将事件发送给每一个subscription对象。这一步EventBus会根据之前查找到的每一个eventType在全局的map表中查找对应的subscriptions集合,并将事件发送给每一个subscription对象,subscription对象接收到事件后会根据内部的subscriberMethod对象的ThreadMode的类型决定在哪个线程中处理该事件,ThreadMode有5中类型:

1)POSITION,该类型是指当前在哪个线程发送的事件就在哪个线程处理事件。

2)MAIN,该类型是指在主线程中处理事件,如果当前线程是主线程就在当前线程处理事件,如果不是主线程就将事件先加入事件队列,然后通过handler切换到主线程后处理。

3)MAIN_ORDERED,该类型是指不管当前是否在主线程中,都先将事件放入事件队列,然后通过handler切换到主线程处理。

4)BACKGROUND,该类型是指在工作线程中处理事件,如果当前线程是工作线程就在当前线程中处理,否则就将事件加入事件队列,然后通过线程池处理事件。

5)ASYNC,该类型是指在工作线程中处理事件,不管当前是否在工作线程中,都将事件加入事件队列,然后通过线程池处理事件。

3.unregister,注销订阅者过程。

EventBus首先会根据当前传入的subscriber对象,在全局的typesBySubscriber的map表中查找当前subscriber中所有事件类型的Class对象集合,然后遍历集合根据每个事件类型的Class对象在全局的subscriptionsByEventType的map表中查找该事件对应的subscription集合,通过对比subscriptions集合中的每个元素的subscriber对象是否是当前的subscriber,如果是就将该subscription元素从集合中删除。完了后会从typesBySubscriber的map表中删除该subscriber的记录。

你可能感兴趣的:(android,eventbus,观察者)