Android EventBus 使用解析

  • EventBus Github地址

  • EventBus是一個(gè)Android端優(yōu)化的publish/subscribe消息總線,簡化了應(yīng)用程序內(nèi)各組件間、組件與后臺(tái)線程間的通信。比如請求網(wǎng)絡(luò),等網(wǎng)絡(luò)返回時(shí)通過Handler或Broadcast通知UI,兩個(gè)Fragment之間需要通過Listener通信,這些需求都可以通過EventBus實(shí)現(xiàn)

  • 優(yōu)點(diǎn):簡化組件之間的通信方式,實(shí)現(xiàn)解耦讓業(yè)務(wù)代碼更加簡潔,可以動(dòng)態(tài)設(shè)置事件處理線程以及優(yōu)先級

  • 缺點(diǎn):目前發(fā)現(xiàn)唯一的缺點(diǎn)就是類似之前策略模式一樣的詬病,每個(gè)事件都必須自定義一個(gè)事件類,造成事件類太多,無形中加大了維護(hù)成本

EventBus.png

EventBus組成部分

  • Event 傳遞的事件對象

  • Subscriber 事件的訂閱者

  • Publisher 事件的發(fā)布者

  • ThreadMode 定義函數(shù)在何種線程中執(zhí)行

使用步驟

  • 添加遠(yuǎn)程依賴
implementation 'org.greenrobot:eventbus:3.0.0'
  • 設(shè)置混淆規(guī)則
-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
    
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}
  • Activity啟動(dòng)時(shí)注冊,才能接收得到消息
EventBus.getDefault().register(MainActivity.this);
  • Activity銷毀時(shí)注銷,才不會(huì)導(dǎo)致內(nèi)存泄露
EventBus.getDefault().unregister(MainActivity.this);
  • 創(chuàng)建事件類型
public class MessageEvent {
    
    public String name;

    public MessageEvent(String name) {
        this.name = name;
    }
}
  • 接收事件
//訂閱事件,并指定該事件在什么線程中執(zhí)行
@Subscribe(threadMode = ThreadMode.MAIN)
public void MesssageEventBus(MessageEvent event){
    // 顯示接收的消息
    textView.setText(event.name);
}
  • 在其他類中發(fā)布事件
//這里發(fā)送的參數(shù)類型必須和接收的參數(shù)類型一致才能接收得到
EventBus.getDefault().post(new MessageEvent("HJQ"));

粘性事件

  • 之前說的使用方法, 都是需要先注冊(register),再post,才能接受到事件; 如果你使用postSticky發(fā)送事件, 那么可以不需要先注冊, 也能接受到事件

  • 創(chuàng)建事件類型

public class StickyEvent {
    
    public String msg;
    
    public StickyEvent(String msg) {
        this.msg = msg;
    }
}
  • 發(fā)布粘性事件
EventBus.getDefault().postSticky(new StickyEvent("我是粘性事件"));
  • 在其他類中接收粘性事件
//和之前的方法一樣,只是多了一個(gè) sticky = true 的屬性.
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
public void onEvent(StickyEvent event){
    textView.setText(event.msg);
}
  • 需要手動(dòng)注冊,注冊后會(huì)自動(dòng)接收并觸發(fā)粘性事件
EventBus.getDefault().register(MainActivity.this);
  • Activity銷毀時(shí)注銷,并移除粘性事件,才不會(huì)導(dǎo)致內(nèi)存泄露
//移除所有粘性事件
EventBus.getDefault().removeAllStickyEvents();
//移除指定類型的粘性事件
//EventBus.getDefault().removeStickyEvent(new StickyEvent("我是粘性事件"));

EventBus.getDefault().unregister(MainActivity.this);

線程調(diào)度

@Subscribe(threadMode = ThreadMode.MAIN)

ThreadMode.MAIN:表示這個(gè)方法在主線程中執(zhí)行
    
ThreadMode.BACKGROUND:表示該方法在后臺(tái)執(zhí)行,不能并發(fā)處理
    
ThreadMode.ASYNC:也表示在后臺(tái)執(zhí)行,可以異步并發(fā)處理
    
ThreadMode.POSTING:表示該方法和消息發(fā)送方在同一個(gè)線程中執(zhí)行

設(shè)置優(yōu)先級

@Subscribe(threadMode = ThreadMode.MAIN, priority = 100)

//終止事件往下傳遞,事件的優(yōu)先級類似廣播的優(yōu)先級,優(yōu)先級越高優(yōu)先獲得消息
EventBus.getDefault().cancelEventDelivery(event);

Android 技術(shù)討論 Q 群:10047167

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容