EventBus手写实现事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EventBus手写实现事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )相关的知识,希望对你有一定的参考价值。
前言
首先声明几个数据结构 , 参考 【EventBus】EventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus ) 博客 , 仿 EventBus , 设置几个重要的集合 ;
一、订阅类-订阅方法缓存集合
METHOD_CACHE
作用仅用于作为订阅方法的缓存类 ,
- Key - 订阅类类型 ;
- Value - 订阅方法 MySubscriberMethod 的集合 ;
每个类可能会创建多个对象 , 当第一个对象注册后 , 就将该类类型与类中的订阅方法 , 都缓存到该 Map<Class<?>, List<MySubscriberMethod>> METHOD_CACHE
集合中 , 这样在注册相同类型的对象时 , 就不需要再次解析该类的所有方法了 ;
每个类只需要反射解析一次即可 ;
如果解析的订阅者类很大 , 开销也很大 , 比如 Activity 这种重量级的类 , 其中有几百个方法 , 如果注册几百个 Activity , 性能消耗还是很客观的 ;
/**
* 方法缓存
* Key - 订阅类类型
* Value - 订阅方法 MySubscriberMethod 的集合
* 取名与 EventBus 一致
*/
private static final Map<Class<?>, List<MySubscriberMethod>> METHOD_CACHE = new HashMap<>();
二、事件类型-订阅者集合
事件类型-订阅者集合 : Map<Class<?>, CopyOnWriteArrayList<MySubscription>> subscriptionsByEventType
;
- Key - 订阅者方法事件参数类型 ;
- Value - 封装 订阅者对象 与 订阅方法 的 MySubscription 集合 ;
在构造函数中初始化该集合 ;
CopyOnWriteArrayList 在写入数据时会拷贝一个副本 , 写完之后 , 将引用指向新的副本 , 该集合的线程安全级别很高 ;
该集合的重要作用就是进行消息转发 , 通过 post 传递进来一个消息对象 , 该消息对象的类型 就是 订阅者方法事件参数类型 , 通过调用 subscriptionsByEventType.get()
方法 , 可以获取到一个CopyOnWriteArrayList<MySubscription>>
集合 , 该集合中的元素 MySubscription
对象就是 接收该类型消息的 订阅者对象 + 订阅方法 的封装类 ;
/**
* Key - 订阅者方法事件参数类型
* Value - 封装 订阅者对象 与 订阅方法 的 MySubscription 集合
* 在构造函数中初始化
* CopyOnWriteArrayList 在写入数据时会拷贝一个副本 ,
* 写完之后 , 将引用指向新的副本 ,
* 该集合的线程安全级别很高
*/
private final Map<Class<?>, CopyOnWriteArrayList<MySubscription>> subscriptionsByEventType;
三、订阅对象-事件类型集合
订阅对象-事件类型集合 : Map<Object, List<Class<?>>> typesBySubscriber
;
- Key - 订阅者对象 ;
- Value - 订阅者对象中所有的订阅方法的事件参数类型集合 ;
在注册时 , 设置该对象对应的订阅方法接收的事件类型 , 在取消注册时 , 可以根据该订阅者对象 , 查找所有订阅方法的事件参数类型 , 然后再到 METHOD_CACHE 中 , 根据事件参数类型 , 查找对应的 MySubscription 集合 , 从而找到 MySubscription 中封装 订阅者对象 + 订阅方法 ;
/**
* 解除注册时使用
* Key - 订阅者对象
* Value - 订阅者对象中所有的订阅方法的事件参数类型集合
*
* 根据该订阅者对象 , 查找所有订阅方法的事件参数类型 , 然后再到 METHOD_CACHE 中 ,
* 根据事件参数类型 , 查找对应的 MySubscriberMethod 集合
* MySubscriberMethod 中封装 订阅者对象 + 订阅方法
*
*/
private final Map<Object, List<Class<?>>> typesBySubscriber;
Lsn09 01:45:42
以上是关于EventBus手写实现事件通信框架 ( 订阅类-订阅方法缓存集合 | 事件类型-订阅者集合 | 订阅对象-事件类型集合 )的主要内容,如果未能解决你的问题,请参考以下文章
EventBus事件通信框架 ( 总结 | 手写事件通信框架完整代码示例 | 测试上述框架 )
EventBus事件通信框架 ( 订阅方法注册 | 注册 事件类型 - 订阅类 + 订阅方法 到指定集合 | 取消注册 数据准备 )
EventBus事件通信框架 ( 订阅方法注册 | 检查订阅方法缓存 | 反射获取订阅类中的订阅方法 )
EventBus事件通信框架 ( 发送事件 | 根据事件类型获取订阅者 | 调用订阅方法 )
EventBus事件通信框架 ( 取消注册 | 获取事件参数类型 | 根据事件类型获取订阅者 | 移除相关订阅者 )
EventBus事件通信框架 ( 发送事件 | 判断发布线程是否是主线程 | 子线程切换主线程 | 主线程切换子线程 )