今天就来重新的复习一下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中取出所有粘性事件处理。