Android 事件匯流排EventBus 原理篇 ———解除註冊篇
阿新 • • 發佈:2018-12-21
閱讀此文章需要會使用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相當,就從當前集合中移除 ,這樣就完成了註冊。會把當前類所有的註冊都解除掉,還不會影響其他類。
到這裡就說完了,我覺得這個模式挺好,主要原理 利用了反射 ,註解 ,快取 ,等實現瞭解耦。