文章目录
一、事件发送 postSingleEventForEventType 方法
二、事件发送 postToSubscription 方法
三、事件发送 invokeSubscriber 方法
一、事件发送 postSingleEventForEventType 方法
首先 , 在同步代码块中 , 根据事件类型获取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType 成员变量中 , 指定 事件类型 键 Key 对应的 值 Value , 即 CopyOnWriteArrayList<Subscription> 集合 ;
每个集合元素都是 Subscription 对象 , 其中封装了 一个订阅者类 和 一个订阅方法 ;
synchronized (this) { // 根据事件类型获取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType // 成员的值 , 即 CopyOnWriteArrayList<Subscription> 集合 // 每个集合元素都是 Subscription 对象 // 其中封装了 一个订阅者类 和 一个订阅方法 subscriptions = subscriptionsByEventType.get(eventClass); }
遍历上述集合 , 调用 postToSubscription 方法 , 进行事件传递后续操作 , 主要是执行 订阅者 中的 订阅方法 ;
// 调用 postToSubscription 方法 , 进行事件传递后续操作 // 主要是执行 订阅者 中的 订阅方法 postToSubscription(subscription, event, postingState.isMainThread);
EventBus.postSingleEventForEventType 方法源码 :
public class EventBus { private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType; private boolean postSingleEventForEventType(Object event, PostingThreadState postingState, Class<?> eventClass) { CopyOnWriteArrayList<Subscription> subscriptions; synchronized (this) { // 根据事件类型获取 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType // 成员的值 , 即 CopyOnWriteArrayList<Subscription> 集合 // 每个集合元素都是 Subscription 对象 // 其中封装了 一个订阅者类 和 一个订阅方法 subscriptions = subscriptionsByEventType.get(eventClass); } // 确保 CopyOnWriteArrayList<Subscription> 集合不为空 if (subscriptions != null && !subscriptions.isEmpty()) { // 遍历上述 CopyOnWriteArrayList<Subscription> 集合 for (Subscription subscription : subscriptions) { // 将当前的事件保存在 ThreadLocal 辅助类中 postingState.event = event; // 将当前的 订阅者 和 订阅方法 封装类 保存在 ThreadLocal 辅助类中 postingState.subscription = subscription; boolean aborted; try { // 调用 postToSubscription 方法 , 进行事件传递后续操作 // 主要是执行 订阅者 中的 订阅方法 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; } }
二、事件发送 postToSubscription 方法
从 Subscription subscription 参数中 , 获取订阅方法的线程模式 , 根据 【EventBus】Subscribe 注解分析 ( Subscribe 注解属性 | threadMode 线程模型 | POSTING | MAIN | MAIN_ORDERED | ASYNC) 博客的运行规则 , 执行线程 ;
订阅方法 的执行 , 实际上是通过反射 , 调用订阅方法 , 并传入指定类型的事件作为参数 , 完成的 ;
invokeSubscriber(subscription, event);
EventBus.postToSubscription 方法源码 :
public class EventBus { 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 { // 假如发布线程是子线程 , 则将事件加入队列 , 通过 Handler 切换线程执行 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); } } }
三、事件发送 invokeSubscriber 方法
通过反射调用订阅方法 ;
EventBus.invokeSubscriber 方法源码 :
public class EventBus { 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); } } }