前一篇文章我们分析了订阅事件的方法register,这篇我们继续淦发送事件的方法post
Android 轻量级线程间通信EventBus
Android EventBus保姆级源码解析(一)注册方法register
Android EventBus保姆级源码解析(二)发送事件post
Android EventBus保姆级源码解析(三)黏性事件原理
总结
按照惯例,先上总结(太长不看版):
- 获取当前线程的Event事件list,把post的事件(Event)加入list,如果当前没有开始分发,则遍历Event事件出队调用
postSingleEvent
开始分发 postSingleEvent
中检查是否允许订阅并分发Event的超类或者接口,然后再交给postSingleEventForEventType
处理postSingleEventForEventType
通过subscriptionsByEventType
列表(<订阅class,<订阅类,订阅方法>>的set),取到监听此Event事件的所有<订阅类,订阅方法>列表,遍历列表用postToSubscription
方法执行处理订阅方法postToSubscription
判断订阅方法的线程模式,在对应的线程中通过反射调用订阅方法
EventBus.post
post方法的使用很简单,这篇就继续从发送事件的post方法剖析源码。
EventBus.getDefault().post(new MessageEvent())
/** Posts the given event to the event bus. */
public void post(Object event) {
// 获取当前线程的PostingThreadState对象,该对象包含事件队列,保存在ThreadLocal中。
PostingThreadState postingState = currentPostingThreadState.get();
//获取当前线程的事件队列,将post的事件添加到队列中
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;
}
}
}
- 其中 PostingThreadState类保存了事件队列、post状态、当前线程等信息,使用ThreadLocal包装保证了线程一致性。
post方法中主要是对分发状态的控制,将当前Event事件入队,然后遍历事件队列出队并调用postSingleEvent
方法对Event事件进行进一步的处理
EventBus.postSingleEvent
private void postSingleEvent(Object event, PostingThreadState postingState) throws Error {
Class<?> eventClass = event.getClass();
boolean subscriptionFound = false;
//这个flag上一篇说过,表示Event是否可以被继承,如果是就查找所有的父类和接口,
if (eventInheritance) {
List<Class<?>> eventTypes = lookupAllEventTypes(eventClass);
int countTypes = eventTypes.size();
//查找所有的父类和接口
for (int h = 0; h < countTypes; h++) {
Class<?> clazz = eventTypes.get(h