1. 程式人生 > >Android訊息傳遞之EventBus 3.0使用詳解(轉載)

Android訊息傳遞之EventBus 3.0使用詳解(轉載)

前面兩篇不僅學習了子執行緒與UI主執行緒之間的通訊方式,也學習瞭如何實現元件之間通訊,基於前面的知識我們今天來分析一下EventBus是如何管理事件匯流排的,EventBus到底是不是最佳方案?學習本篇知識之前建議先回顧一下前兩篇知識:Android訊息傳遞之Handler訊息機制(一),Android訊息傳遞之元件間傳遞訊息(二)。

訊息傳遞相關文章地址:

Android訊息傳遞之Handler訊息機制
Android訊息傳遞之元件間傳遞訊息
Android訊息傳遞之EventBus 3.0使用詳解
Android訊息傳遞之基於RxJava實現一個EventBus - RxBus
EventBus產生需求背景:

在做專案的時候往往需要應用程式內各元件間、元件與後臺執行緒間的通訊。比如耗時操作,等耗時操作完成後通過Handler或Broadcast將結果通知給UI,N個Activity之間需要通過Listener通訊,之前的實現方式我們在Android訊息傳遞之元件間傳遞訊息(二)中已經介紹過了,其實這些都可以通過EventBus輕鬆實現,EventBus通過釋出/訂閱(publish/subscribe)方式來管理事件匯流排。其實EventBus的實現方式更加接近上篇文章的方式二,不同的是EventBus通過註解和反射機制 將訂閱者連同訂閱函式儲存起來,然後在傳送訂閱的時候 遍歷訂閱函式陣列進行呼叫,其實從這方面就可以EventBus執行效率多少會受到一點影響。

EventBus介紹:

 EventBus出自greenrobot,和之前大名鼎鼎的GreenDao出自同一家。之前一直使用的是2.4版本,今天我們將學習分析最新的Event 3.0,EventBus 3.0 最新的特性就是加入了註解,通過註解的方式 告知訂閱函式執行在哪個執行緒中。

 github地址:https://github.com/greenrobot/EventBus

 官方文件:http://greenrobot.org/eventbus/documentation

EventBus主要角色:

Event 傳遞的事件物件
Subscriber 事件的訂閱者
Publisher 事件的釋出者
ThreadMode 定義函式在何種執行緒中執行
官網給出的各種角色的協作圖

EventBus配置:

EventBus框架也是採用建造者模式設計的,可以通過EventBusBuilder來設定一些配置資訊,例如設定debug模式下要丟擲異常

EventBus eventBus=EventBus.builder().throwSubscriberException(BuildConfig.DEBUG).build();
EventBus示例:

之前做圖片社交App的時候,需要處理一個點贊資料的同步,比如在作品的詳情頁點贊 需要同時更新列表頁該作品的點贊數量,這裡還是以此為例。

1.)build.gradle新增引用

compile ‘org.greenrobot:eventbus:3.0.0’
2.)定義一個事件型別

複製程式碼
public class DataSynEvent {
private int count;

public int getCount() {
    return count;
}

public void setCount(int count) {
    this.count = count;
}

}
複製程式碼
3.)訂閱/解除訂閱

訂閱

EventBus.getDefault().register(this);//訂閱
解除訂閱

EventBus.getDefault().unregister(this);//解除訂閱
4.)釋出事件

EventBus.getDefault().post(new DataSynEvent());
5.)訂閱事件處理

@Subscribe(threadMode = ThreadMode.MAIN) //在ui執行緒執行
public void onDataSynEvent(DataSynEvent event) {
    Log.e(TAG, "event---->" + event.getCount());
}

ThreadMode總共四個:
NAIN UI主執行緒
BACKGROUND 後臺執行緒
POSTING 和釋出者處在同一個執行緒
ASYNC 非同步執行緒
6.)訂閱事件的優先順序

事件的優先順序類似廣播的優先順序,優先順序越高優先獲得訊息

@Subscribe(threadMode = ThreadMode.MAIN,priority = 100) //在ui執行緒執行 優先順序100
public void onDataSynEvent(DataSynEvent event) {
Log.e(TAG, “event—->” + event.getCount());
}
7.)終止事件往下傳遞

傳送有序廣播可以終止廣播的繼續往下傳遞,EventBus也實現了此功能

EventBus.getDefault().cancelEventDelivery(event) ;//優先順序高的訂閱者可以終止事件往下傳遞
8.)處理程式碼混淆

複製程式碼
-keepattributes Annotation
-keepclassmembers class ** {
@org.greenrobot.eventbus.Subscribe ;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

Only required if you use AsyncExecutor

-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
(java.lang.Throwable);
}
複製程式碼
EventBus黏性事件

EventBus除了普通事件也支援粘性事件,這個有點類似廣播分類中的粘性廣播。本身粘性廣播用的就比較少,為了方便理解成訂閱在釋出事件之後,但同樣可以收到事件。訂閱/解除訂閱和普通事件一樣,但是處理訂閱函式有所不同,需要註解中新增sticky = true

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true) //在ui執行緒執行
public void onDataSynEvent(DataSynEvent event) {
Log.e(TAG, “event—->” + event.getCount());
}
傳送粘性事件

EventBus.getDefault().postSticky(new DataSynEvent());
對於粘性廣播我們都比較清楚屬於常駐廣播,對於EventBus粘性事件也類似,我們如果不再需要該粘性事件我們可以移除

EventBus.getDefault().removeStickyEvent(new DataSynEvent());
或者呼叫移除所有粘性事件

EventBus.getDefault().removeAllStickyEvents();
EventBus processor使用:

EventBus提供了一個EventBusAnnotationProcessor註解處理器來在編譯期通過讀取@Subscribe()註解並解析,
處理其中所包含的資訊,然後生成java類來儲存所有訂閱者關於訂閱的資訊,這樣就比在執行時使用反射來獲得這些訂閱者的
資訊速度要快.

1.)具體使用:在build.gradle中新增如下配置

複製程式碼
buildscript {
dependencies {
classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8’
}
}
apply plugin: ‘com.neenbedankt.android-apt’

dependencies {
compile ‘org.greenrobot:eventbus:3.0.0’
apt ‘org.greenrobot:eventbus-annotation-processor:3.0.1’
}
apt {
arguments {
eventBusIndex “com.whoislcj.eventbus.MyEventBusIndex”
}
}
複製程式碼
2.)使用索引

此時編譯一次,自動生成生成索引類。在\build\generated\source\apt\PakageName\下看到通過註解分析生成的索引類,這樣我們便可以在初始化EventBus時應用我們生成的索引了。

自動生成的程式碼

複製程式碼
/* This class is generated by EventBus, do not edit. /
public class MyEventBusIndex implements SubscriberInfoIndex {
private static final Map