分析EventBus.getDefault().post()方法
public void
post
(Object event) {
PostingThreadState postingState =
currentPostingThreadState
.get()
;
List<Object> eventQueue = postingState.
eventQueue
;
eventQueue.add(event)
;
if
(!postingState.
isPosting
) {
postingState.
isMainThread
= isMainThread()
;
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对象加入eventQueue后,然后就执行postSingleEvnet()
点进去
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) {
logger.log(Level.FINE, "No subscribers registered for event " + eventClass);
}
if (sendNoSubscriberEvent && eventClass != NoSubscriberEvent.class &&
eventClass != SubscriberExceptionEvent.class) {
post(new NoSubscriberEvent(this, event));
}
}
}
由debug得知,这里enventInheritance是为true的,那么会执行if(evnetInheritance)下面的语句,
lookupEventTypes是从缓存里获取所有的eventTypes,这个放下面再分析
获取到所有evnetTypes后,循环执行postSingleEventForType()
下面看postSingleEventForType
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;
}
可以看到这里用了CopyOnWriteArrayList<Subscription> ,可以理解为是一个线程安全的ArrayList
然后还有一个重要的类Subscription,
点进去看
final class Subscription {
final Object subscriber;
final SubscriberMethod subscriberMethod;
/**
* Becomes false as soon as {@link EventBus#unregister(Object)} is called, which is checked by queued event delivery
* {@link EventBus#invokeSubscriber(PendingPost)} to prevent race conditions.
*/
volatile boolean active;
Subscription(Object subscriber, SubscriberMethod subscriberMethod) {
this.subscriber = subscriber;
this.subscriberMethod = subscriberMethod;
active = true;
}
@Override
public boolean equals(Object other) {
if (other instanceof Subscription) {
Subscription otherSubscription = (Subscription) other;
return subscriber == otherSubscription.subscriber
&& subscriberMethod.equals(otherSubscription.subscriberMethod);
} else {
return false;
}
}
@Override
public int hashCode() {
return subscriber.hashCode() + subscriberMethod.methodString.hashCode();
}
}
Subscription就只是把一个subsciber和 subscriberMehtod 另外加一个boolean变量active放在了一个对象中
这样有什么用呢?我的理解是,一个subscription代表一个订阅事件,因为一个event post出去,可能有多个
subscriber接收到,那么一个subscriber和一个event绑定就是一个订阅事件,多个subscriber和同一个event,
就是多个订阅事件
继续看
postSingleEventForEventType
subscriptions =
subscriptionsByEventType
.get(eventClass)
;
看这句,从subscriptionByEventType中获取subscriptons
这个subscriptionsByEventType是什么,它是一个Map,它里面的value是在EventBus.getDefault().register(this)
建立订阅时put进去的,请参考EventBus源码分析1
拿到subscriptions后,就开始循环执行
postToSubscription
点进去
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 MAIN_ORDERED:
if (mainThreadPoster != null) {
mainThreadPoster.enqueue(subscription, event);
} else {
// temporary: technically not correct as poster not decoupled from subscriber
invokeSubscriber(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);
}
}
可以看,这里是根据threadMode区分执行
我们在MainActivity中的,threadMode是MAIN
那么这里就执行
if (isMainThread) {
invokeSubscriber(subscription, event);
} else {
mainThreadPoster.enqueue(subscription, event);
}
由Debug得知,isMainThread是true
那么就执行invokeSubscriber(),点进去
void invokeSubscriber(Subscription subscription, Object event) {
try {
subscription.subscriberMethod.method.invoke(subscription.subscriber, event);
} catch (InvocationTargetException e) {
handleSubscriberException(subscription, event, e.getCause());
} catch (IllegalAccessException e) {
throw new IllegalStateException("Unexpected exception", e);
}
}
可以看到,这里在用反射的方式,用Method.invoke的方式调用方法
实际就是在调用@Subscribe(threadMode = MAIN)下面的方法
综上分析,就是实现了post一个Event对象后,调用关联的方法的过程