1.總體設計
一般來說我們都知道EventBus 使用起來非常的簡單,但是如果不使用可不可以嘛,答案肯定是可以的,但是會增加很多額外的代碼。普通的BroadCastReceiver 其實就可以滿足最基本的需求。然后廣播使用相對比較麻煩,會增加業務量。
說實話若不是EventBus的出現,BroadCastReceiver(廣播)還是有一定的市場的,比較其中的設計思路有很多大同,都使用觀察者模式見下圖
觀察者模式的核心是被觀察者持有觀察者的引用,觀察者對被觀察者的變化做出反應。
然后我們回來看一下EventBus設計的特點,一般來說我們常見的觀察者與被觀察者都是成對出現的,這樣會減少代碼的耦合,不會有很多觀察者觀察同一事件。在觀察多個事件變化時候通常會有多個被觀察者。然而EventBus將自身作為一個事件處理中心,故此EventBus翻譯為事件總線,是非常恰當的。
EventBus自身作為一個被觀察者,高度抽象了原有的各個被觀察者,將原有的被觀察者都集中一起,這樣不要寫很多重復的BroadCastReceiver代碼,只需要在有事件變化的時候EventBus自身做出處理便可以。下面我們分析一下注冊的流程。
2.Register 流程
其中維護兩個特別的map? 見下圖,subscriptionsByEventType 是以事件為key,method和threadType以及subscrber(activity或者fragment)為構造的subscription作為value。(是不是典型的觀察者模式,被觀察者持有訂閱者的引用??)
typesBySubscriber是以subscriber為key,event作為value的 map。
注冊的過程就是講需要被觀察的事件統一綁定到EventBus,一般來說事件是被觀察的一方,所以activity或是fragment被設計成觀察者。這樣Eventbus 在收到事件/event 變化的時候會直接作出變化。
3.post 流程
首先從PostingThreadState 這個對象中取出發送信息的狀態,其中包含一個事件的發送隊列。
練的核心方法是postSingleEvent,那么我們看下這個方法
其中邏輯核心代碼postSingleEventForEventType 故名思議就是根據不同事件類型事件/event發給其中的訂閱了該事件的訂閱者
通過event取出相應的訂閱者列表。這時候代碼是不是看起來很容易理解,前面我們說過的維護的map? subscriptionsByEventType,這個時候就上場表演了,直接根據不同事件類型取出 所有訂閱者subscriptions,其中subscription的構造就包括了其中的 subscriber (一般是activity /fragment)引用,方法,方法類型。這樣直接執行便使得我們預先注冊的onEvent方法生效了。
本次的EventBus大體就到這里了。總結起來就是activity(中方法)作為訂閱者接收訂閱事件通知,但是其實各種操作都在EventBus之中完成了調用。無論是訂閱者還是事件發布者都只與EventBus有關。代碼耦合度低,易于管理。