上篇文章介绍了EventBus注册流程, 本篇文章简介EventBus发送事件的流程
EventBus源码(一)
1.发送事件Demo的代码
EventBus.getDefault().post("我是小名同学");
2.源码流程图
2.1源码流程
/** Posts the given event to the event bus. */
public void post(Object event) {
//获取当前线程的一个状态 类型是 ThreadLoacal
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 队列 发送消息
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
postingState.isMainThread = false;
}
}
}
post事件,获取到当前的线程的信息PostingThreadState, 包括当前线程的事件集合,状态,以及subscription信息,在进行遍历事件队列,通过 postSingleEventForEventType逐步对每个事件进行处理(省略postSingleEvent方法)
private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) {
CopyOnWriteArrayList<Subscription> subscriptions;
synchronized (this) {
//根据event类型 获取到 subscription集合
subscriptions = subscriptionsByEventType.get(eventClass);
}
if (subscriptions != null && !subscriptions.isEmpty()) {
//遍历subscription集合, 并把事件写入到postingState中
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;
}
//根据subscription获取到SubscribeMethod信息, 并且可以获取到 注解的 线程类型
private void postToSubscription(Subscription subscription, Object event, boolean isMainThread) {
switch (subscription.subscriberMethod.threadMode) {
case POSTING:]
//统一线程执行 接受订阅事件
invokeSubscriber(subscription, event);
break;
case MAIN:
//主线程执行 判断是否在主线程 如果在直接执行,不在通过Handler进行线程调度
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);
}
}
//执行订阅方法
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);
}
}
以上就是EventBus的post流程.