EventBus的源码分析:Post流程


在上一篇讲注册的时候讲到,会把一个EventType和与他相关的订阅方法放到subscriptionsEventType这个map里,所以先找出与这个event相关的父类和接口:
postingState是线程安全的,ThreadLocal类的,每次只分发一个event,标志器是isPosting,如果在分发过程中有新的事件需要分发,就加入到事件队列里,等上个事件执行完后,再执行,并且分发完所有的事件衙就重置isPosting。
/** Posts the given event to the event bus. */
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;
        }
    }
}
接下来看如何分发一个event:首先是看是否需要事件继承,默认是需要。如果需要的话,就需要找出这个事件类型的父类和相关接口,再分发,如果不需要,就直接分发。如果在分发的过程中没有找到相关的订阅者,就重新分发一个NoSubScriberEvent.
private void postSingleEvent(Object event , PostingThreadState postingState) throws Error {
    Class<?> eventClass = event.getClass()
;
    boolean
subscriptionFound = false;
    if
( eventInheritance ) {
        List<Class<?>> eventTypes = lookupAllEventTypes(eventClass)
;
        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)) ;
       
}
    }
}
找出这个事件类型的父类和接口:
/** Looks up all Class objects including super classes and interfaces. Should also work for interfaces. */
private List<Class<?>> lookupAllEventTypes(Class<?> eventClass) {
   
synchronized ( eventTypesCache ) {
        List<Class<?>> eventTypes =
eventTypesCache .get(eventClass) ;
        if
(eventTypes == null ) {
            eventTypes =
new ArrayList<Class<?>>() ;
           
Class<?> clazz = eventClass ;
            while
(clazz != null ) {
                eventTypes.add(clazz)
;
               
addInterfaces(eventTypes , clazz.getInterfaces()) ;
               
clazz = clazz.getSuperclass() ;
           
}
           
eventTypesCache .put(eventClass , eventTypes) ;
       
}
       
return eventTypes ;
   
}
}
接下来就是分发流程:在分发的过程中,注意要根据当前线程是否是主线程来执行,如果是主线程,就交给Handler,否则交给eventBus的线程池执行,最后都通过invodeSubscriber方法来反射扫行订阅者。
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;
}

private void postToSubscription (Subscription subscription , Object event , boolean isMainThread) {
   
// 根据事件的执行线程类型,来找到相应的线程池,如果是主线程执行,而且本身就是主线程就交给当前进程,否则交给 handler 分发消息。
   
switch (subscription. subscriberMethod . threadMode ) {
       
case PostThread :
            invokeSubscriber(subscription
, event) ;
            break;
        case
MainThread :
           
if (isMainThread) {
                invokeSubscriber(subscription
, event) ;
           
} else {
               
mainThreadPoster .enqueue(subscription , event) ;
           
}
           
break;
        case
BackgroundThread :
           
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 ) ;
   
}
}


你可能感兴趣的:(EventBus的源码分析:Post流程)