今天就来重新的复习一下EventBus
的实现原理
EventBus
是一个 Android
开发中常用的事件发布/订阅库,它通过解耦不同组件之间的交互,使得代码更加简洁易读。
优点:框架本身简单、简洁。
使用方法
EventBus
是一个单例,订阅者通过他的EventBus.getDefault().register(this)
,来注册,通过EventBus.getDefault().unregister(this)
来解除绑定,这通常在activity
或者fragment
的生命周期中调用。
@Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
@Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
在其他代码组件发送消息:
EventBus.getDefault().post(new MessageEvent());
订阅者接收到消息,对应MessageEvent
参数的订阅方法就会被调用,方法可以定义被调用的执行线程
//ThreadMode.POSTING,默认的线程模式,在那个线程发送事件就在对应线程处理事件,避免了线程切换,效率高。
//ThreadMode.MAIN,如在主线程(UI线程)发送事件,则直接在主线程处理事件;如果在子线程发送事件,则先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
//ThreadMode.MAIN_ORDERED,无论在那个线程发送事件,都先将事件入队列,然后通过 Handler 切换到主线程,依次处理事件。
//ThreadMode.BACKGROUND,如果在主线程发送事件,则先将事件入队列,然后通过线程池依次处理事件;如果在子线程发送事件,则直接在发送事件的线程处理事件。
//ThreadMode.ASYNC,无论在那个线程发送事件,都将事件入队列,然后通过线程池处理。
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event){
Log.d("execute",event.toString());
}
原理
注册与反注册
订阅者在注册时后,通过反射原理找出订阅者所有含
subscribe
注解修辞的方法,并且保存在一个HashMap
中(typesBySubscriber
),这个HashMap
以注册对象为key
,SubscriberMethod
为value
。同时也会保存一个以EventType
为key
,Subscription
对象集合为value
的的HashMap
(subscriptionsByEventType
),然后对粘性事件做特殊处理,粘性事件将会放到一个HashMap
中(stickyEvents
),这个HashMap
以EventType
为key
,Event对象
为value
,会一直存在内存中,需要人为维护。
同样的,反注册主要也是以删除
typesBySubscriber
和subscriptionsByEventType
这两个HashMap
中的关联对象操作处理的
发送消息
将消息保存在列队中,然后交给正在处于
posting
的方法执行线程循环出列, 并且调用postSingleEvent()
,这里根据情况找出消息的所有父类,并且执行postSingleEventForEventType()
,这里会在subscriptionsByEventType
找出所有的订阅者,调用postToSubscription()
,这里会调用不同的ThreadMode进行不同的线程调度或者执行。
线程调度
线程调度主要是通过
Handler
实现的,发送消息时最终会调用到HandlerPoster的enqueue()
方法。
HandlerPoster的enqueue()
方法主要就是将subscription
、event
对象封装成一个PendingPost
对象,然后保存到队列里,之后通过Handler
切换到主线程,在handleMessage()
方法将中将PendingPost
对象循环出队列,交给invokeSubscriber()
方法做进一步处理。
粘性事件
在注册订阅者的时候,会去
stickEvent
中取出所有粘性事件处理。