EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )相关的知识,希望对你有一定的参考价值。
一、事件发送 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);
}
}
}
以上是关于EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )的主要内容,如果未能解决你的问题,请参考以下文章
EventBusEventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )
EventBusEventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )
EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )
EventBusEventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )
EventBusEventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus )
EventBusEventBus 源码解析 ( 事件发送 | 发布线程为 子线程 切换到 主线程 执行订阅方法的过程分析 )