EventBus3.0的事件的分發時經過EventBus類中的post(粘性事件爲postSticky)方法,post與postSticky的惟一區別就是,在postSticky內部首先會向EventBus類中的stickyEvents集合中添加事件類實例,而後在調用post方法;post方法的參數就是咱們本身定義的事件類的實例;java
public void post(Object event) { PostingThreadState postingState = currentPostingThreadState.get(); List<Object> eventQueue = postingState.eventQueue; eventQueue.add(event); if (!postingState.isPosting) { postingState.isMainThread = Looper.getMainLooper() == Looper.myLooper(); postingState.isPosting = true; if (postingState.canceled) { throw new EventBusException("Internal error. Abort state was not reset"); } try { while (!eventQueue.isEmpty()) { postSingleEvent(eventQueue.remove(0), postingState); } } finally { postingState.isPosting = false; postingState.isMainThread = false; } } }
在事件分發以前,首先經過currentPostingThreadState內獲取PostingThreadState;currentPostingThreadState是一個ThreadLocal<PostingThreadState>,咱們知道ThreadLocal在java是保存每一個線程中獨立的數據,通常狀況下,經過ThreadLocal.set() 到線程中的對象是該線程本身使用的對象,其餘線程是不須要訪問的,也訪問不到的;而ThreadLocal存儲的PostingThreadState類,就是個信息類;async
final static class PostingThreadState { final List<Object> eventQueue = new ArrayList<Object>();//事件類隊列 boolean isPosting; boolean isMainThread;//是不是主線程 Subscription subscription; Object event;//事件類實例 boolean canceled; }
獲取到當前線程的PostingThreadState,並將須要處理的事件類實例添加到PostingThreadState的eventQuenue隊列中;若是當前線程的Looper與主線程的Looper一致,這PostingThreadState的isMainThread爲true;而PostingThreadState類中的isPosting來判斷是否正在進行分發;最後經過postSingleEvent方法循環進行數據的分發處理;oop
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error { Class<?> eventClass = event.getClass(); boolean subscriptionFound = false; if (eventInheritance) {//是否觸發訂閱了該事件的基類以及接口類的相應方法 List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);//查找event類全部的基類以及接口 int countTypes = eventTypes.size(); for (int h = 0; h < countTypes; h++) { Class<?> clazz = eventTypes.get(h); subscriptionFound |= postSingleEventForEventType(event, postingState, clazz); } } else { subscriptionFound = postSingleEventForEventType(event, postingState, eventClass); } if (!subscriptionFound) { if (logNoSubscriberMessages) { Log.d(TAG, "No subscribers registered for event " + eventClass); } if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class && eventClass != SubscriberExceptionEvent.class) { post(new NoSubscriberEvent(this, event)); } } }
postSingleEvent方法首先經過lookupAllEventTypes方法查找出全部的event類中全部的基類以及接口;而後對這些循環進行分發;post
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { subscriptions = subscriptionsByEventType.get(eventClass); } if (subscriptions != null && !subscriptions.isEmpty()) { for (Subscription subscription : subscriptions) { postingState.event = event; postingState.subscription = subscription; boolean aborted = false; try { 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; }
在postSingleEventForEventType方法中咱們能夠看到咱們從EventBus類中subscriptionsByEventType中取出全部匹配的Subscription;並將Subscription實例中的event,subscription賦值給postingState;this
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) { switch (subscription.subscriberMethod.threadMode) { case POSTING: invokeSubscriber(subscription, event); break; case MAIN: if (isMainThread) { invokeSubscriber(subscription, event); } else { mainThreadPoster.enqueue(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); } }
在postToSubscription方法中,subscription.subscriberMethod.threadMode 4種線程模型,當線程模型爲POSTING 時,直接執行invokeSubscriber方法,效率也最快;而invokeSubscriber方法也很簡單,就是反射中的invoke方法;spa
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);線程