返回
EventBus源码解析上(较详细)
Android
2023-11-23 07:05:51
EventBus是一个非常优秀的开源框架,具有解耦事件的发送者和接收者,简化组件间的通信,避免复杂和容易出错的依赖以及生命周期等的优点。所以对其内部源码的实现进行了一番探究。根据自己的理解,对于其注册与发送的逻辑分析,分为上下两部分。
ThreadMode.MAIN:表示无论事件线程是什么,事件处理方法总是运行在UI线程。
ThreadMode.BACKGROUND:事件处理方法将始终在后台线程执行。
ThreadMode.ASYNC:事件处理方法将会被提交到一个单独的线程中。
因为事件的分发采用PostThread,从分发的流程可以看出,在事件的分发过程中,针对不同的线程模式会采用不同的线程进行分发,然后再分发给对应的注册者进行处理。分发不同线程模式的事件始终是串行的,而不是并发。否则接收者的处理方法就会存在并发问题。
事件发送:
- post方法的声明:public void post(Object event)
- post方法的实现:
public void post(Object event) {
//判断发送的事件是否为null
if (event == null) {
throw new NullPointerException("Event to post cannot be null.");
}
//判断事件发布者是否被移除
boolean dispatched = false;
synchronized (this) {
//先判断全局的订阅者是否包含该事件的订阅者,若包含则发布事件
dispatched = postSingleEventForEventType(event, isMainThread);
//发布全局事件失败,则尝试发布粘性事件
if (!dispatched && stickyEventMap != null && !stickyEventMap.isEmpty()) {
dispatched = publishStickyEvent(event);
}
}
//发布事件是否成功
if (!dispatched) {
logPostNoSubscriber(event);
}
}
事件发布主要分为两种情况,一种是发布全局事件,另一种是发布粘性事件。
-
发布全局事件:根据事件的类型获取对应的订阅者集合,然后对订阅者集合中的每一个订阅者进行事件分发。在分发事件的过程中,根据订阅者的线程模式不同,采用不同的线程进行事件的分发。
-
发布粘性事件:当没有订阅者订阅某个事件时,这个事件就会变成一个粘性事件,当有新的订阅者订阅该事件时,就会收到这个粘性事件。
EventBus的事件发送逻辑相对比较简单,但是却非常强大。它支持多种线程模式,可以满足不同的使用场景。