EventBusEventBus 源码解析 ( 取消订阅 )
Posted 韩曙亮
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EventBusEventBus 源码解析 ( 取消订阅 )相关的知识,希望对你有一定的参考价值。
一、取消订阅
【EventBus】EventBus 使用示例 ( 最简单的 EventBus 示例 ) 示例中 , 在 MainActivity
中调用
// 取消注册
EventBus.getDefault().unregister(this);
方法 , 取消订阅 ;
取消订阅是以对象为单位的 , 一旦调用了 EventBus
的 unregister
方法 , 并传入 订阅者对象 , 则该订阅者对象中的所有 订阅方法 , 都会被 取消订阅 ;
在 【EventBus】EventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus ) 博客中 , 介绍到注册订阅者 , 是将 事件参数类型 和 订阅者信息 添加到 Map<Class<?>, CopyOnWriteArrayList> subscriptionsByEventType
集合中 ;
那么取消订阅者 , 也是从 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
集合中移除相应的数据 ;
如何根据 订阅者对象 找到对应的数据 , 就需要依靠 Map<Object, List<Class<?>>> typesBySubscriber
集合进行辅助查找 , 首先根据 Map<Object, List<Class<?>>> typesBySubscriber
集合 , 查找订阅者对象对应的 参数类型对象 ;
然后根据 参数类型对象 到 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
集合中查找参数类型对应的 订阅者类 对应的订阅者方法 , 从上述集合中移除相应的 订阅者类及相关的订阅方法 , 即可完成 取消订阅的操作 ;
public class EventBus {
/** 从所有事件类中注销给定订阅服务器。 */
public synchronized void unregister(Object subscriber) {
// 获取该对象中的所有订阅方法的参数类型集合
List<Class<?>> subscribedTypes = typesBySubscriber.get(subscriber);
if (subscribedTypes != null) {
for (Class<?> eventType : subscribedTypes) {
// 根据参数类型 , 移除该对象中相应的订阅方法
unsubscribeByEventType(subscriber, eventType);
}
typesBySubscriber.remove(subscriber);
} else {
logger.log(Level.WARNING, "Subscriber to unregister was not registered before: " + subscriber.getClass());
}
}
}
二、取消订阅 unsubscribeByEventType 方法
在 unsubscribeByEventType
方法中 , 通过参数 Class<?> eventType
从 Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType
集合中获取 Subscription 集合列表 ;
然后检查 Subscription 列表中 订阅者对像 是否是 取消注册的对象 , 如果是 , 直接将相应的 Subscription 对象从列表中移除 ;
/** 仅按事件类型更新订阅,不按订阅类型更新订阅!调用方必须更新typesBySubscriber。 */
private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {
// 通过参数类型获取 Subscription 列表
List<Subscription> subscriptions = subscriptionsByEventType.get(eventType);
if (subscriptions != null) {
int size = subscriptions.size();
for (int i = 0; i < size; i++) {
Subscription subscription = subscriptions.get(i);
// 检查 Subscription 列表中 订阅者对像 是否是 取消注册的对象
// 如果是 , 直接将相应的 Subscription 对象从列表中移除
if (subscription.subscriber == subscriber) {
subscription.active = false;
subscriptions.remove(i);
i--;
size--;
}
}
}
}
以上是关于EventBusEventBus 源码解析 ( 取消订阅 )的主要内容,如果未能解决你的问题,请参考以下文章
EventBusEventBus 源码解析 ( 注册订阅者 | 订阅方法 | 查找订阅方法 )
EventBusEventBus 源码解析 ( 事件发送 | 线程池中执行订阅方法 )
EventBusEventBus 源码解析 ( 事件发送 | postToSubscription 方法 | EventBus 线程模式处理细节 )
EventBusEventBus 源码解析 ( 事件发送 | EventBus.post 方法 | EventBus.postSingleEvent 方法 )
EventBusEventBus 源码解析 ( 注册订阅者总结 | 从封装的数据结构角度分析 EventBus )
EventBusEventBus 源码解析 ( 事件发送 | 发布线程为 子线程 切换到 主线程 执行订阅方法的过程分析 )