EventBus

大大大大大發表於2019-11-23

一、原理

1、註冊 EventBus.getDefault().register()

  1. 使用反射,在註冊的時候(EventBus.getDefault().register(this)),獲取類物件中被註解Subscribe註解的方法。
  2. 使用兩個HashMap儲存資訊。這樣可以 物件-》方法引數-》方法
  3. subscriptionsByEventType是一個HashMap,儲存了以eventType(方法引數型別)為key,Subscription物件(方法包裝物件)集合為value的鍵值對。
  4. typesBySubscribere也是一個HashMap,儲存了以當前要註冊類的物件為key,註冊類中訂閱事件的方法的引數型別的集合為value的鍵值對
  5. 如果有粘性事件的訂閱,會查詢stickyEvents這個HashMap集合,在進行方法註冊的時候就執行一次。

2、取消註冊 EventBus.getDefault().unregister()

  1. 先找出物件註冊的方法的引數型別,List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
  2. 再遍歷subscribedTypes,找出符合引數型別的list。 List subscriptions = subscriptionsByEventType.get(eventType);
  3. 上述兩個HashMap 對應註冊時存資訊的兩個,typesBySubscriber和subscriptionsByEventType
  4. 遍歷獲取的封裝方法物件,去掉需要取消註冊的物件的相關資訊

3、傳送事件 EventBus.getDefault().post("Hello World!")

  1. 根據引數型別,先把時間post到ThreadLocal物件的佇列中,再迴圈獲取該佇列中的事件,處理。
  2. 處理的過程是先獲取到該事件型別的訂閱者列表,再遍歷這些訂閱者,根據訂閱者資訊(最主要的是執行的執行緒資訊threadMode)進行反射執行方法。

4、傳送粘性事件 EventBus.getDefault().postSticky("Hello World!")

  1. 把事件存在stickyEvents這個集合中。
  2. 走一遍post()方法。就是第三步中普通的傳送事件流程
  3. 使用粘性事件注意處理好空指標異常。可能在註冊的時候就有事件執行,而某些用到的變數未初始化。

相關文章