路漫漫其修远兮
01. 手写EventBus框架——源码分析1
02. 手写EventBus框架——源码分析2
03. 手写EventBus框架——动手_整体架构设计
04. 手写EventBus框架——动手_终结
上篇文章 手写EventBus框架——源码分析1 从EventBus的源码出发 分析了 注册,取消注册、发布 和缓存订阅事件等主体功能,了解它的一个实现机制以及事件总线的设计。
基本上分析完上一篇文章就已经可以实现基本的EventBus了,然而,EventBus是个优秀的框架,有很多地方值得学习,这篇文章接着对源码进行解析补充:
- Sticky 粘性事件实现
- 事件优先级实现
- 其他一些
o.O Sticky粘性
什么是粘性事件? **
相信大部分同学都知道,像EventBus会经常用到,包括广播也是有粘性事件分发的这个概念的。那么针对于不熟悉的同学我就简单说一下,o.O 真的是简单说一下~** :简单讲,就是在注册之前分发事件,而后事件注册以后也能接收到分发的事件。
大白话:先post 在 register, 也能收到分发事件。
上篇分析到:post 方式的实现机制是:通过反射立刻执行我们订阅的方法。
然而粘性事件的性质是 分发事件发生在订阅事件之前,订阅事件发生在分发事件之后,那么带着这个疑问,我们来看一下:
先发布postSticky
:
public void postSticky(Object event) {
synchronized (stickyEvents) {
//加入粘性列表
stickyEvents.put(event.getClass(), event);
}
post(event);
}
注册粘性:
public void register(Object subscriber) {
//...
subscribe(subscriber, subscriberMethod);
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
//判断是粘性事件
if (subscriberMethod.sticky) {
if (eventInheritance) {
//循环
Set<Map.Entry<Class<?>, Object>> entries = stickyEvents.entrySet();
for (Map.Entry<Class<?>, Object> entry : entries) {
Class<?> candidateEventType = entry.getKey();
// 如果事件相匹配
if (eventType.isAssignableFrom(candidateEventType)) {
Object stickyEvent = entry.getValue();
//检查并执行
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
} else {
Object stickyEvent = stickyEvents.get(eventType);
//检查并执行
checkPostStickyEventToSubscription(newSubscription, stickyEvent);
}
}
}
** ~ 柳暗花明又一村 **
分析完后大叹一声:原来如此!
那粘性事件的流程我们就比较清晰明了了。
流程:
- 发布时:将 发布事件 缓存起来;
- 当粘性事件被订阅的时候 : 检查缓存器,如果相匹配 则执行该订阅事件,从而执行一次完整的粘性事件。
注意:
这边执行完粘性事件以后 没有将缓存清除,那么下次再注册该粘性方法时还会执行。那么这时候需要调用removeStickyEvent
清除粘性缓存。
o.O 事件优先级
其中有事件优先级的一个概念。看一下它的一个设计
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
//...
subscribe(subscriber, subscriberMethod);
//...
}
private void subscribe(Object subscriber, SubscriberMethod subscriberMethod) {
Class<?> eventType = subscriberMethod.eventType;
//...
List<Class<?>> subscribedEvents = typesBySubscriber.get(subscriber);
if (subscribedEvents == null) {
subscribedEvents = new ArrayList<>();
typesBySubscriber.put(subscriber, subscribedEvents);
}
//....
}
比较简单,控制缓存列表的顺序。
注意:
这边的优先级 只是针对 订阅类型 也就是eventType
。
o.O 其他一些
比较简单,也没什么好讲的 ...
下一篇: 03. 手写EventBus框架——动手_整体架构设计
希望我的文章不会误导在观看的你,如果有异议的地方欢迎讨论和指正。
如果能给观看的你带来收获,那就是最好不过了。