Android EventBus 使用解析

  • EventBus Github地址

  • EventBus是一個(gè)Android端優(yōu)化的publish/subscribe消息總線,簡化了應(yīng)用程序內(nè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ù)代碼更加簡潔,可以動態(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啟動時(shí)注冊,才能接收得到消息
EventBus.getDefault().register(MainActivity.this);
  • Activity銷毀時(shí)注銷,才不會導(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);
}
  • 需要手動注冊,注冊后會自動接收并觸發(fā)粘性事件
EventBus.getDefault().register(MainActivity.this);
  • Activity銷毀時(shí)注銷,并移除粘性事件,才不會導(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:表示該方法在后臺執(zhí)行,不能并發(fā)處理
    
ThreadMode.ASYNC:也表示在后臺執(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容