1. 程式人生 > >Android 事件匯流排EventBus 原理篇 ———解除註冊篇

Android 事件匯流排EventBus 原理篇 ———解除註冊篇

閱讀此文章需要會使用EventBus。本文原始碼是3.0之後的版本。

直接看原始碼

 /** Unregisters the given subscriber from all event classes. */
    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());
        }
    }

之前一篇介紹過,解除註冊的時候就是第二個集合,當前tag是key,可以拿到引數的型別集合 ,然後遍歷引數的型別集合,然後把每種引數的型別都解除註冊就完成了註冊,這樣會有一個問題就是會把所有類訂閱的都會解除,看看怎麼避免的 

 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--;
                }
            }
        }
    }

這裡 和我說的一樣,從第一個集合當中拿到當前引數 key型別的所有訂閱,然後進行遍歷,當 tag(subscriber)一樣的時候,就說明是我們要解除的當前類的,這個時候我們從集合當中把它們移除掉,就完成了解除註冊的功能。ps :i--,和size-- 分別是防止下表出錯和越界異常。

總結一下 :

反註冊的流程 就是根據tag 去第二個集合中拿到引數型別的集合(也就是當前類註冊的方法所有的引數型別),然後遍歷引數型別,從第一個集合當中 根據引數型別能夠拿到所有的 訂閱類 tag ,最後遍歷當前引數型別的所有訂閱類,逐一排除,如果tag相當,就從當前集合中移除 ,這樣就完成了註冊。會把當前類所有的註冊都解除掉,還不會影響其他類。

到這裡就說完了,我覺得這個模式挺好,主要原理 利用了反射 ,註解 ,快取 ,等實現瞭解耦。