【EventBus】EventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )
文章目錄
- 一、事件發(fā)送 postSingleEventForEventType 方法
- 二、事件發(fā)送 postToSubscription 方法
- 三、事件發(fā)送 invokeSubscriber 方法
一、事件發(fā)送 postSingleEventForEventType 方法
首先 , 在同步代碼塊中 , 根據(jù)事件類型獲取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType 成員變量中 , 指定 事件類型 鍵 Key 對(duì)應(yīng)的 值 Value , 即 CopyOnWriteArrayList<Subscription> 集合 ;
每個(gè)集合元素都是 Subscription 對(duì)象 , 其中封裝了 一個(gè)訂閱者類 和 一個(gè)訂閱方法 ;
synchronized (this) {// 根據(jù)事件類型獲取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType // 成員的值 , 即 CopyOnWriteArrayList<Subscription> 集合 // 每個(gè)集合元素都是 Subscription 對(duì)象 // 其中封裝了 一個(gè)訂閱者類 和 一個(gè)訂閱方法 subscriptions = subscriptionsByEventType.get(eventClass);}遍歷上述集合 , 調(diào)用 postToSubscription 方法 , 進(jìn)行事件傳遞后續(xù)操作 , 主要是執(zhí)行 訂閱者 中的 訂閱方法 ;
// 調(diào)用 postToSubscription 方法 , 進(jìn)行事件傳遞后續(xù)操作// 主要是執(zhí)行 訂閱者 中的 訂閱方法 postToSubscription(subscription, event, postingState.isMainThread);EventBus.postSingleEventForEventType 方法源碼 :
public class EventBus {private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {CopyOnWriteArrayList<Subscription> subscriptions;synchronized (this) {// 根據(jù)事件類型獲取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType // 成員的值 , 即 CopyOnWriteArrayList<Subscription> 集合 // 每個(gè)集合元素都是 Subscription 對(duì)象 // 其中封裝了 一個(gè)訂閱者類 和 一個(gè)訂閱方法 subscriptions = subscriptionsByEventType.get(eventClass);}// 確保 CopyOnWriteArrayList<Subscription> 集合不為空 if (subscriptions != null && !subscriptions.isEmpty()) {// 遍歷上述 CopyOnWriteArrayList<Subscription> 集合 for (Subscription subscription : subscriptions) {// 將當(dāng)前的事件保存在 ThreadLocal 輔助類中 postingState.event = event;// 將當(dāng)前的 訂閱者 和 訂閱方法 封裝類 保存在 ThreadLocal 輔助類中 postingState.subscription = subscription;boolean aborted;try {// 調(diào)用 postToSubscription 方法 , 進(jìn)行事件傳遞后續(xù)操作// 主要是執(zhí)行 訂閱者 中的 訂閱方法 postToSubscription(subscription, event, postingState.isMainThread);aborted = postingState.canceled;} finally {postingState.event = null;postingState.subscription = null;postingState.canceled = false;}if (aborted) {break;}}return true;}return false;} }二、事件發(fā)送 postToSubscription 方法
從 Subscription subscription 參數(shù)中 , 獲取訂閱方法的線程模式 , 根據(jù) 【EventBus】Subscribe 注解分析 ( Subscribe 注解屬性 | threadMode 線程模型 | POSTING | MAIN | MAIN_ORDERED | ASYNC) 博客的運(yùn)行規(guī)則 , 執(zhí)行線程 ;
訂閱方法 的執(zhí)行 , 實(shí)際上是通過(guò)反射 , 調(diào)用訂閱方法 , 并傳入指定類型的事件作為參數(shù) , 完成的 ;
invokeSubscriber(subscription, event);EventBus.postToSubscription 方法源碼 :
public class EventBus {private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {// 獲取該 訂閱方法 的線程模式 switch (subscription.subscriberMethod.threadMode) {case POSTING:// 不做線程切換 , 直接在發(fā)布線程中調(diào)用 invokeSubscriber(subscription, event);break;case MAIN:if (isMainThread) {// 假如在主線程中 , 直接調(diào)用 invokeSubscriber(subscription, event);} else {// 假如發(fā)布線程是子線程 , 則將事件加入隊(duì)列 , 通過(guò) Handler 切換線程執(zhí)行 mainThreadPoster.enqueue(subscription, event);}break;case MAIN_ORDERED:if (mainThreadPoster != null) {mainThreadPoster.enqueue(subscription, event);} else {// temporary: technically not correct as poster not decoupled from subscriberinvokeSubscriber(subscription, event);}break;case BACKGROUND:if (isMainThread) {backgroundPoster.enqueue(subscription, event);} else {invokeSubscriber(subscription, event);}break;case ASYNC:asyncPoster.enqueue(subscription, event);break;default:throw new IllegalStateException("Unknown thread mode: " + subscription.subscriberMethod.threadMode);}} }三、事件發(fā)送 invokeSubscriber 方法
通過(guò)反射調(diào)用訂閱方法 ;
EventBus.invokeSubscriber 方法源碼 :
public class EventBus {void invokeSubscriber(Subscription subscription, Object event) {try {// 通過(guò)反射調(diào)用 訂閱方法 subscription.subscriberMethod.method.invoke(subscription.subscriber, event);} catch (InvocationTargetException e) {handleSubscriberException(subscription, event, e.getCause());} catch (IllegalAccessException e) {throw new IllegalStateException("Unexpected exception", e);}} } 《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的【EventBus】EventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【EventBus】EventBus 源
- 下一篇: 【EventBus】EventBus 源