事件總線定義:事件總線是對發布-訂閱模式的一種實現。它是一種集中式事件處理機制,允許不同的組件之間進行彼此通信而又不需要相互依賴,達到一種解耦的目的。
事件總線的處理流程:
Event Bus就相當於一個介於Publisher和Subscriber中間的橋梁。它隔離了Publlisher和Subscriber之間的直接依賴,接管了所有事件的發布和訂閱邏輯,並負責事件的中轉。分析一下,如果EventBus要接管所有事件的發布和訂閱,那它則需要有一個容器來記錄事件源和事件處理。那又如何觸發呢?有了事件源,我們就自然能找到綁定的事件處理邏輯,通過反射觸發
EventBus是Android下高效的發布/訂閱事件總線機制。作用是可以代替傳統的Intent,Handler,Broadcast或接口函數在Fragment,Activity,Service,線程之間傳遞數據,執行方法。特點是代碼簡潔,是一種發布訂閱設計模式(Publish/Subsribe),或稱作觀察者設計模式
1.事件總線維護一個事件源與事件處理的映射字典;
2.通過單例模式,確保事件總線的唯一入口;
3.利用反射完成事件源與事件處理的初始化綁定;
4.提供統一的事件注冊、取消注冊和觸發接口。
事件總線EventBus的設計
為什么要設計EventBus,因為他是領域驅動設計中比不可少的模塊,它承擔傳輸數據的作用,它可以解耦模塊之間的耦合性。
如何對EventsBus進行定義。1、EventBus是基於JVM內部的數據傳輸系統,不是JMS;EventBus的核心對象為Event和EventHandler。
EventBus的模塊結構如下:
EventService對外提供各種服務,它依賴queue,bus,annotatin。
queue包為EventService提供事件源。
bus包提供兩種事件總線:ClassEventBus和TopicEventBus。
annotatin包提供兩種注解方式@ClassEventHandler和@TopicEventHandler。
queue包結構如下:
QueueWrapper是對各種Event的包裝,使他們能夠統一放入Queue。
EventQueue本質上阻塞隊列,負責接收事件和提取事件。
Bus包結構如下:
EventBus是Facade類,統籌ClassEventBus和TopicEventBus,ClassEventBus和TopicEventBus在處理訂閱着、分發事件是相似的,區別在Class是針對事件的類型,而TopicEventBus針對的主題。以ClassEventBus的為例,結構如下:
Key2List是 是對 Map<key,List<Value>> 中List<Value>的封裝,統一各種常用的操作,EventType2Event是個事件類型對應的事件列表,用於緩存控制。Class2Handler保存事件的訂閱者,ClassEventBus每發布一次事件,都會Class2Handler中取得訂閱者。
notifyHandlers(Event)是Bus一個關鍵設計點。如果是采用一個線程循環處理所有事件的方式,在處理復雜計算的事情時,會影響其他訂閱者。如果是采用每個線程對應一個訂閱者,則在高並發的情況下,線程會增加,系統資源占用率提高。如果是采用Executor來應對,則是折中的辦法。
訂閱者想處理ClassEvent,必須實現ClassEventHandler。
annotation包是以注解的方式來調用bus包下各種EventBus。如果想讓業務Facade類,監聽某個事件,則給方法加上@ClassEventHandler或@TopicEventHandler。然后讓AnnotationProcessor調用process即可。以ClassEventHandler對應的模塊為例,來介紹其結構:
AnnotationProcessor的process處理過程如下:
1、從object對象,找出帶有ClassEventHanlder的函數。
2、把方法和Object,整合到ProxClassHandler。
3、ProxyClassHanlder注冊到EventService中。
ProxyClassHandler最重要的邊上onEvent(Evenet),它的功能是以反射的方式調用指定方法。
最后是介紹EventService,它的結構很簡單:
其中,最關鍵的時RunTask,他繼承Runnable類,在run()中,線程不停地從eventQueue獲取事件,然后發布給訂閱者。當然RunTask在EventService初始化的時候,就會生成,知道EventService銷毀。
最終的類圖