从几个关键的数据存储结构角度分析 EventBus 注册订阅者过程 ;
Map<Class<?>, CopyOnWriteArrayList> subscriptionsByEventType 集合
在 EventBus 中的 subscriptionsByEventType
成员变量 , 保存的是 HashMap 集合 ,
public class EventBus {
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
}
在 EventBus.subscribe
方法中 , 获取订阅方法参数类型就是上述 Key 键 ;
// 获取订阅方法参数类型 , 可以是任意类型 , 自定义的 MessageEvent 消息类型
Class<?> eventType = subscriberMethod.eventType;
先封装该 订阅者 对象 与 订阅方法 到 Subscription
中 ,
// Subscription 中封装了一个订阅者对象和一个订阅方法
Subscription newSubscription = new Subscription(subscriber, subscriberMethod);
然后从 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
成员变量中获取 对应 消息类型 的 Subscription
集合 ;
如果发现没有该消息类型对应的 CopyOnWriteArrayList<Subscription>
集合 , 则先创建一个集合 , 再放入到 subscriptionsByEventType
成员中 ;
然后在将新封装的 Subscription
对象 , 放到对应的 CopyOnWriteArrayList<Subscription>
集合中 , 注意放入的时候 , 查询是否有设置优先级属性 , 如果有 , 按照优先级顺序放置 ;
int size = subscriptions.size();
for (int i = 0; i <= size; i++) {
// 处理订阅方法优先级 , 重新进行排列
if (i == size || subscriberMethod.priority > subscriptions.get(i).subscriberMethod.priority) {
subscriptions.add(i, newSubscription);
break;
}
}
这样就完成了 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
成员的封装工作 ;
该成员变量的作用很明显 , 在发布者发送消息到消息中心后 , 消息中心根据传入的消息类型 , 查找对应的 订阅者实例对象 和 订阅方法 , 可以直接调用对应的订阅方法 ;
Map<Object, List<Class<?>>> typesBySubscriber 集合
private final Map<Object, List<Class<?>>> typesBySubscriber;
是 EventBus
的成员变量 ;
可以根据订阅者对象查询 该订阅者对象 中的 订阅方法 中的参数集合 , 根据参数可以到 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
集合中查询对应的 订阅者对象 和 订阅方法 ;
该 typesBySubscriber
集合的作用很明显 , 在取消注册时 , 可以快速查询到 该订阅者对象 注册了哪些方法 , 将其从 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
集合中移除 , 就可以达到取消订阅的目的 ;