【EventBus】EventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )
文章目录
- 一、EventBus 注册订阅者
- 二、订阅方法
- 三、查找订阅方法 findSubscriberMethods 方法
- 四、查找订阅方法 findUsingInfo 方法
- 五、查找订阅方法 findUsingReflectionInSingleClass
一、EventBus 注册订阅者
EventBus 中调用 EventBus.getDefault().register(this) 注册订阅者 ; 该方法中主要进行了如下 222 个步骤 :
- ① 获取 订阅者 集合 , 查找当前订阅类中符合条件的订阅方法集合 ;
- ② 遍历 订阅者 集合 , 进行事件订阅 , 保存数据 , 这些数据就是一些映射关系
二、订阅方法
SubscriberMethod 对订阅的方法进行了一些封装 , 包括了方法的 Method 对象 Method method , 线程模式 ThreadMode threadMode , 事件类型 Class<?> eventType, 优先级 int priority , 粘性 boolean sticky 等 ;
/** 由EventBus内部使用并生成订户索引。 */ public class SubscriberMethod {final Method method;final ThreadMode threadMode;final Class<?> eventType;final int priority;final boolean sticky;/** Used for efficient comparison */String methodString; }三、查找订阅方法 findSubscriberMethods 方法
订阅方法缓存机制 : 从缓存中获取 订阅方法 , METHOD_CACHE 缓存是一个 HashMap 集合 ;
如果订阅者有很多方法 , 如果每次订阅都要查询所有的方法 , 如果遍历一次 Activity 的所有方法 很消耗性能 ; 因此这里引入了缓存机制 ;
第一次订阅时 , 将方法都放在缓存集合中 , 如果第二次订阅 , 不用再次查找方法 ;
如果缓存中没有订阅方法 , 那么说明这是第一次查找订阅方法 , 一般情况下都是调用 subscriberMethods = findUsingInfo(subscriberClass) 方法 , 获取订阅方法 ;
class SubscriberMethodFinder {// 方法缓存集合private static final Map<Class<?>, List<SubscriberMethod>> METHOD_CACHE = new ConcurrentHashMap<>();List<SubscriberMethod> findSubscriberMethods(Class<?> subscriberClass) {// 从缓存中获取 订阅方法 , METHOD_CACHE 缓存是一个 HashMap 集合// 如果订阅者有很多方法 , 如果每次订阅都要查询所有的方法 , 很消耗性能 // 第一次订阅时 , 将方法都放在集合中 // 如果第二次订阅 , 不用再次查找方法List<SubscriberMethod> subscriberMethods = METHOD_CACHE.get(subscriberClass);if (subscriberMethods != null) {return subscriberMethods;}// 如果缓存中没有订阅方法 , 那么说明这是第一次查找订阅方法// ignoreGeneratedIndex 属性默认是 false // 是否忽略注解生成器 if (ignoreGeneratedIndex) {subscriberMethods = findUsingReflection(subscriberClass);} else {// 一般情况下 , 调用的是该方法 subscriberMethods = findUsingInfo(subscriberClass);}if (subscriberMethods.isEmpty()) {throw new EventBusException("Subscriber " + subscriberClass+ " and its super classes have no public methods with the @Subscribe annotation");} else {METHOD_CACHE.put(subscriberClass, subscriberMethods);return subscriberMethods;}} }下面分析 findUsingInfo 方法 ;
四、查找订阅方法 findUsingInfo 方法
FindState 是辅助类 , 其中进行了状态保存等信息 ;
参数 Class<?> subscriberClass 是订阅者类 , 将订阅类设置到 FindState 查找状态类对象中 ;
该方法的核心是调用了 findUsingReflectionInSingleClass(findState) 方法 , 进行后续查找操作 ;
class SubscriberMethodFinder {private List<SubscriberMethod> findUsingInfo(Class<?> subscriberClass) {// FindState 是辅助类 , 其中进行了状态保存等信息 FindState findState = prepareFindState();// 将订阅类设置到 FindState 查找状态类对象中 findState.initForSubscriber(subscriberClass);// 订阅类的字节码类while (findState.clazz != null) {findState.subscriberInfo = getSubscriberInfo(findState);// 从 查找状态 中 获取订阅信息 , 如果订阅信息不为空 , 进行如下处理 if (findState.subscriberInfo != null) {SubscriberMethod[] array = findState.subscriberInfo.getSubscriberMethods();for (SubscriberMethod subscriberMethod : array) {if (findState.checkAdd(subscriberMethod.method, subscriberMethod.eventType)) {findState.subscriberMethods.add(subscriberMethod);}}} else { // 从 查找状态 中 获取订阅信息 , 如果订阅信息为空 , 进行如下处理 findUsingReflectionInSingleClass(findState);}// 查找订阅类的上级父类 , 继续进行循环 findState.moveToSuperclass();}return getMethodsAndRelease(findState);} }五、查找订阅方法 findUsingReflectionInSingleClass
通过反射获取订阅者类中的所有方法 , 遍历 订阅者 类中的所有方法 , 过滤掉不符合条件的方法 , 将符合条件的方法封装到 findState.subscriberMethods 集合中 ;
过滤方案 :
- 订阅方法的参数个数肯定只有 1 个 ;
- 订阅方法上有 @Subscribe 注解 ;
- @Subscribe 注解属性判断 ;
- @Subscribe 注解线程模式判断 ;
总结
以上是生活随笔为你收集整理的【EventBus】EventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 【EventBus】EventBus 源
- 下一篇: 【EventBus】EventBus 源