原理
EventBus的核心工作机制如下图
在EventBus3.0架构图:
EventBus类
在EventBus3.0框架的内部,核心类就是EventBus,订阅者的注册/订阅,解除注册,以及事件的分发全部在这个核心类中实现;
对于EventBus对象的创建,在框架内部是通过单例模式进行创建;我们平时在代码中通过EventBus类中的静态方法getDefault 获取实例对象;
public static EventBus getDefault() {
if (defaultInstance == null) {
synchronized (EventBus.class) {
if (defaultInstance == null) {
defaultInstance = new EventBus();
}
}
}
return defaultInstance;
} public EventBus() {
this(DEFAULT_BUILDER);
}
从代码中可以看出在创建EventBus对象的时候内部会初始化一些字段的配置,在EventBus类内部存在许多的Map字段;当post分发时,就是从这些map中查询出相应的消息处理事件;
Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType: key:为我们自定义的事件类,value:订阅者的回调方法列表,subscriptionsByEventType 在订阅者进行订阅/注册时添加相应的map关系;当EventBus接收到一个事件时,会在subscriptionsByEventType 中根据事件类型查找出所有监听了这个时间的订阅者和回调方法等信息;我们知道Subscription类中包含回调方法封装的SubscriptionMethod类,在里面保存了我们反射执行方法的各种参数等信息;
Map<Object, List<Class<?>>> typesBySubscriber: key:订阅者的实例对象,value:订阅者中所监听的所有的事件类型,一个订阅者可以有多个消息处理函数,因此会有多个事件类型;这个map还可以在取消订阅/注册的时候快速查找到相应的事件类型,进行快速删除subscriptionsByEventType中订阅者的注册信息;
Map<Class<?>, Object> stickyEvents:key:粘性事件的事件类型,value:粘性事件的事件类型的实例;由于粘性事件的数据是存储在内存中,当被订阅者发送粘性事件时,首先会向stickyEvents 集合中添加数据,当订阅者进行粘性事件订阅/注册时,就会从stickyEvents取出粘性事件的事件实例进行分发,保证了当我注册/订阅粘性事件时,也可以接收到以前被订阅者发送的事件信息; 在EventBus对象初始化过程中,也会对EventBus内部的其他对象进行创建:
EventBus(EventBusBuilder builder) {
subscriptionsByEventType = new HashMap<>();
typesBySubscriber = new HashMap<>();
stickyEvents = new ConcurrentHashMap<>();
mainThreadPoster = new HandlerPoster(this, Looper.getMainLooper(), 10);//主线程处理
backgroundPoster = new BackgroundPoster(this);//后台线程处理
asyncPoster = new AsyncPoster(this);//异步线程
indexCount = builder.subscriberInfoIndexes != null ? builder.subscriberInfoIndexes.size() : 0;
subscriberMethodFinder = new SubscriberMethodFinder(builder.subscriberInfoIndexes,
builder.strictMethodVerification, builder.ignoreGeneratedIndex);//查找订阅者的消息处理函数的类型
logSubscriberExceptions = builder.logSubscriberExceptions;
logNoSubscriberMessages = builder.logNoSubscriberMessages;
sendSubscriberExceptionEvent = builder.sendSubscriberExceptionEvent;
sendNoSubscriberEvent = builder.sendNoSubscriberEvent;
throwSubscriberException = builder.throwSubscriberException;
eventInheritance = builder.eventInheritance;
executorService = builder.executorService;
}