天天看點

android資料傳輸利器--Event Bus模式

本文章同時發表在安卓巴士,歡迎大家前去觀摩指導。

場景描述:

對于事件總線架構知道的人可能不多,但是進行過Android開發的程式猿們應該都有這樣的經曆。

1、在開發的過程中遇到過從Activity-A跳轉到Activity-B,然後需要在Activity-B處理完某些工作之後回調Activity-A中的某個函數,但Activity又不能手動建立對象來設定一個Listener的情況。

2、遇到在某個Service中更新Activity或Fragment中的界面等元件之間的互動問題。

3、徹底退出應用的功能實作,需要管理activity清單的煩惱。

4、背景下載下傳需要通知各個元件的情況。

5、Fragment之間的通信問題。

有什麼用:

事件總線架構簡化了Activity、Fragment、Service等元件之間的互動,讓代碼更簡潔,耦合性更低,相比以往的廣播或者序列化對象來傳遞,事件總線就簡約和高效了很多。Event Bus模式也被稱為Message Bus或者釋出者/訂閱者(publisher/subscriber)模式,可以讓兩個元件互相通信,但是他們之間并不互相知曉。

主要作用

1、它承擔傳輸資料的作用

2、它可以解耦子產品之間的耦合性

3、簡化代碼邏輯

4、相比傳統方法要更加高效

5、消息可以在任意線程和位置發送

6、接受消息并執行邏輯的方法可以在任意線程運作(可以設定運作的線程)

7、消息與接收者可以是一對多的關系(類似廣播)

基本的用法:

市面上這麼多的事件總線架構他們的用法都是大同小異的,基本包括下面幾個邏輯和使用步驟

1、注冊資訊訂閱者/接收者(可以了解為需要被調用的那一方)

2、定義事件(類似handle中的Message)

3、實作訂閱者的方法(消息發送後被調用的方法)

4、發送消息

幾個主流架構:

EventBus架構

android資料傳輸利器--Event Bus模式

EventBus是一個Android端優化的publish/subscribe消息總線,簡化了應用程式内各元件間、元件與背景線程間的通信。

特點:

1、在EventBus中,使用約定來指定事件訂閱者以簡化使用。即所有事件訂閱都都是以onEvent開頭的函數,具體來說,函數的名字是onEvent,onEventMainThread,onEventBackgroundThread,onEventAsync這四個。簡單了解就是需要被調用的方法名稱需要按照上面的規則來寫,不能自定義。

2、效率高

Github位址和文檔:

https://github.com/greenrobot/EventBus

Otto架構

Otto 是Android系統的一個Event Bus模式類庫。用來簡化應用元件間的通信。

特點:

1、使用注解的方式,@Subscribe 注解告訴Bus該函數訂閱了一個事件,該事件的類型為該函數的參數類型;而@Produce注解告訴Bus該函數是一個事件産生者,産生的事件類型為該函數的傳回值。函數名稱可以自定義。

2、訂閱函數預設執行在主線程中

官方網站:

http://square.github.io/otto/

Github位址:

https://github.com/square/otto

AndroidEventBus架構

android資料傳輸利器--Event Bus模式

這是一個Android平台的事件總線架構, 它簡化了Activity、Fragment、Service等元件之間的互動,很大程度上降低了它們之間的耦合,使得我們的代碼更加簡潔,耦合性更低,提升我們的代碼品質。

AndroidEventBus類似于觀察者模式,通過register函數将需要訂閱事件的對象注冊到事件總線中,然後根據@Subscriber注解來查找對象中的訂閱方法,并且将這些訂閱方法和訂閱對象存儲在map中。當使用者在某個地方釋出一個事件時,事件總線根據事件的參數類型和tag找到對應的訂閱者對象,最後執行訂閱者對象中的方法。

特點:

1、使用注解的方式,類似Otto,函數名稱可以自定義

2、訂閱函數支援tag(類似廣播接收器的Action)使得事件的投遞更加準确,能适應更多使用場景。(可以直接設定執行線程)

Github位址:

https://github.com/bboyfeiyu/AndroidEventBus

中文版文檔:

https://github.com/bboyfeiyu/AndroidEventBus/blob/master/README-ch.md

EventBus、AndroidEventBus和Otto對比:

名稱 性能 訂閱函數執行其他線程是否友善 函數名稱是否可以自定義 使用難度
EventBus
AndroidEventBus
Otto 否(要實作接口)

EventBus和Otto性能對比:

在性能上其實已經有了比較廣泛的認同,但到底注解方式和約定事件名稱這兩種之間存在多大的性能差距呢?在這裡我拿到了官方的一個測試工具EventBusPerformance來進行一個小測試,對比一下兩大類型的架構性能的差别。

本次測試可能不夠嚴謹隻給大家作為參考。測試手機為魅族MX3,安卓4.4.4系統

android資料傳輸利器--Event Bus模式

測試内容:

1. 發消息

分别發送1000條消息到需要在目前線程,主線程,背景線程執行的函數,每個測試10次取平均值。

下面的是一些比較平均的測試結果大家可以參考

android資料傳輸利器--Event Bus模式
android資料傳輸利器--Event Bus模式
android資料傳輸利器--Event Bus模式

從結果中看到,Eventbus在各個測試中比Otto快50%以上,個别測試中比Otto快近4倍。

發送資訊到主線程比發送到其他線程要慢。

2. 注冊訂閱者

兩個架構分别注冊訂閱者1000個,重複10次取平均值。

android資料傳輸利器--Event Bus模式

上圖為選取的比較平均的一次測試。

從結果中很容易看到Eventbus同樣是比Otto要快了不少。

3. 注冊訂閱者但是不登出

兩個架構分别注冊1000個訂閱者不登出,測試10次取平均值

android資料傳輸利器--Event Bus模式

圖為選取的比較平均的一次測試

從測試中可以看到不登出訂閱者的速度要比登出訂閱者的操作耗時,同樣在性能在Eventbus要好一些。

測試總結

1、注解方式和約定事件名稱這兩種之間性能比較明顯,Eventbus性能比較突出。

2、在發送消息的測試中可以知道,同一線程的消息處理要快一些,誇線程操作比較慢,主程序的操作最慢(主程序這個還有待研究大家參考下就好了)。

3、在注冊訂閱者的測試中不登出訂閱者的速度要比登出訂閱者的操作耗時,大家看到這個在使用的過程中使用完了一定要記得登出訂閱者,這個是會影響性能的!

畢竟我不是專業的測試員,若對測試有疑問歡迎大家下載下傳本測試工具