源码解析-unregister

来源:互联网 发布:网游推荐知乎 编辑:程序博客网 时间:2024/05/21 18:42

1、一行代码解除订阅

EventBus.getDefault().unregister(this); // 解除订阅

2、unregister()

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 {        Log.w(TAG, "Subscriber to unregister was not registered before: " + subscriber.getClass());    }}

在注册事件的时候我们分析过,typesBySubscriber的类型为:

private final Map<Object, List<Class<?>>> typesBySubscriber;

里面存放的数据类容:键为订阅者,也即某个activity或fragment对象,值为一个listl列表,list中存放的是事件类型,例如:com.example.event.EventMsg。通过代码很容易发现首先通过键找到对应的值,然后调用unsubscribeByEventType方法,最后调用remove方法移除绑定关系。下面看看unsubscribeByEventType方法具体做了什么工作。

2.1 unsubscribeByEventType

private void unsubscribeByEventType(Object subscriber, Class<?> eventType) {    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);            if (subscription.subscriber == subscriber) {                subscription.active = false;                subscriptions.remove(i);                i--;                size--;            }        }    }}

在注册事件的时候我们分析过,subscriptionsByEventType的类型为:

private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;

里面存放的数据类容:键为事件类型,例如:com.example.event.EventMsg,值为list列表,元素为Subscription对象,Subscription中具有订阅者信息及订阅的方法信息(方法名称:onDataSynEvent,事件类型等等)。分析代码,可以知道去除list中相关的订阅者,也即解除事件与订阅者之间的关系。

总结

解除订阅的过程,主要是移除事件单例中事件与订阅者之间的关系,保存事件与订阅者关系的数据主要有subscriptionsByEventType和typesBySubscriber两个变量,因此去除两个变量中订阅者与事件的关系即取消订阅。