【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 源