在上一篇讲注册的时候讲到,会把一个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;
}
}
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)) ;
}
}
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 ;
}
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 ) ;
}
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 ) ;
}
}