首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

EventBus 3.0 完整指南:Android 事件總線最佳實踐與線程模型深度解析

     編輯:Java 綜合教學

為什麼選擇 EventBus?

傳統 Android 組件通訊依賴 Intent、Handler、BroadcastReceiver、介面回調,缺點明顯:

  • 代碼冗長、耦合度高
  • 跨組件/執行緒傳值麻煩
  • 生命週期管理易洩漏

EventBus 採發布/訂閱模式,優勢:開銷極小、代碼極簡、徹底解耦、支援多線程模型、支援 Sticky 事件。建議直接使用 3.0.0 正式版(組織 org.greenrobot:eventbus:3.0.0),勿用 2.4 或 3.0 beta。

三大核心角色

  • Event (事件):任意類型物件(POJO 即可)
  • Subscriber (訂閱者):接收事件的類,方法以 @Subscribe 註解標記
  • Publisher (發布者):任意執行緒呼叫 EventBus.getDefault().post(event)

四大線程模型

完整使用流程

1. 依賴引入

implementation 'org.greenrobot:eventbus:3.0.0'

2. 定義事件類

public class MessageEvent {
    private String message;
    public MessageEvent(String msg) { this.message = msg; }
    public String getMessage() { return message; }
}

3. 註冊/註銷 (通常在 Activity/Fragment 生命週期)

@Override protected void onStart() {
    super.onStart();
    EventBus.getDefault().register(this);
}
@Override protected void onStop() {
    EventBus.getDefault().unregister(this);
    super.onStop();
}

4. 發送事件

// 任意執行緒、任意位置
EventBus.getDefault().post(new MessageEvent("下載完成"));

5. 處理事件 (方法名任意,需 public + @Subscribe)

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
    textView.setText(event.getMessage());
    Toast.makeText(this, event.getMessage(), Toast.LENGTH_SHORT).show();
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onBackground(MessageEvent event) {
    // 執行耗時操作
}

實戰範例:跨 Activity 傳遞下載結果

效果演示動圖

MainActivity (訂閱者,展示四種線程模型 ID)

public class MainActivity extends AppCompatActivity {
    @Subscribe(threadMode = ThreadMode.POSTING)
    public void onPost(MessageEvent e) { tvDefault.setText(Thread.currentThread().getId()+""); }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMain(MessageEvent e) { 
        tvMain.setText(Thread.currentThread().getId()+"");
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND)
    public void onBackground(MessageEvent e) { tvBackground.setText(Thread.currentThread().getId()+""); }

    @Subscribe(threadMode = ThreadMode.ASYNC)
    public void onAsync(MessageEvent e) { tvAsync.setText(Thread.currentThread().getId()+""); }
}

FirstActivity (發布者,子執行緒模擬下載)

btn.setOnClickListener(v -> new Thread(() -> {
    Thread.sleep(1000);
    EventBus.getDefault().post(new MessageEvent("網絡下載的文本"));
}).start());

進階特性

  • Sticky Event:postSticky(event),新訂閱者立即收到最近一次黏性事件(適合初始化數據)
  • 優先級:@Subscribe(priority = 1),數值大者優先接收,可攔截/修改事件
  • 事件繼承:訂閱父類事件可接收子類事件
  • ProGuard 保護:-keepclassmembers class ** { @org.greenrobot.eventbus.Subscribe *; }

常見坑與避坑指南

  1. 忘記 unregister → 記憶體洩漏、重複接收
  2. POSTING 模式執行耗時操作 → 卡死發布執行緒 (若為 UI 則 ANR)
  3. 事件類未定義 public 建構子 → 反序列化/黏性事件失效
  4. 模組化專案需使用 EventBus.builder().installDefaultEventBus() 共享實例
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
ThreadMode執行執行緒適用場景
POSTING (預設)發布執行緒輕量操作,不可耗時
MAINUI 主執行緒更新 UI、Toast、Dialog
BACKGROUND後台執行緒 (發布在 UI 則新建,否則沿用)耗時運算、資料庫、網路請求
ASYNC新建獨立後台執行緒極耗時任務、完全隔離發布者