1. 程式人生 > >訊息傳遞機制之EventBus的使用詳細

訊息傳遞機制之EventBus的使用詳細

 EventBus是怎樣管理事件匯流排的, 是不是最佳處理訊息的方案?讓我們一同來學習和認識.

EventBus由來

    在面對應用程式內元件間, 元件與後臺執行緒間的通訊. 又如我們在處理耗時操作時, 等到耗時操作完成後通過Handler或者Broadcast去更新UI, 但是面對多個Activity之間需要通過Listener通訊完成. 但是這些問題我們可以通過EventBus來完成.它是通過釋出/訂閱的方式來管理事件匯流排 .通過註解和反射機制將訂閱者連同訂閱函式儲存起來, 然後在傳送訂閱的時候遍歷訂閱函式陣列進行呼叫, 但是這種形式會影響到EventBus的執行效力.

EventBus的介紹

    EventBus出自greenrobot, 與GreenDao是一家. 而EventBus3.0框架採用了建造者模式, 並加入註解, 通過註解的方式告知訂閱函式執行在哪一個執行緒中.

EventBus主要角色

  •     Event 傳遞的事件物件
  •     Subscriber 事件的訂閱者
  •     Publisher事件的釋出者
  •     ThreadMode 定義函式在那種執行緒中執行

官網給出的各種角色的協作圖


EventBus使用

  1. 在build.gradle中新增引用
compile 'org.greenrobot:eventbus:3.0.0'

    2. 定義一個事件型別

 public class EventInfoBean {
     public String msg;
     public EventInfoBean(String msg) {
         this.msg = msg;
      }
  }

    3.訂閱事件

EventBus.getDefault().register(this);

    4. 釋出事件

EventBus.getDefault().post(new 	EventInfoBean("eventBus傳送的訊息"))

    5. 解除訂閱(一般放在onDestroy()中)

EventBus.getDefault().unregister(this);
    6.訂閱事件處理
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventInfoBean info) {
        Toast.makeText(getApplicationContext(), "接收到的訊息..." + info.msg, Toast.LENGTH_SHORT).show();
    }

    7.訂閱事件的優先順序

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

    @Subscribe(threadMode = ThreadMode.MAIN,priority = 100)
    public void onDataSynEvent(EventInfoBean event) {
        Log.e(TAG, "event---->" + event.msg);
    }

    8.終止事件傳遞

    EventBus在傳送有序廣播的時候可以終止廣播的往下傳遞

 EventBus.getDefault().cancelEventDelivery(event) ;

    9. 程式碼混淆

-keepattributes *Annotation*
-keepclassmembers class ** {
    @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

EventBus執行緒模型說明

    ThreadMode.MAIN  

        無論任何執行緒中釋出事件, 事件處理函式都會在main執行緒中執行.該方法可以用來更新UI, 但是不能處理耗時操作

    ThreadMode.BACKGROUND

        如果釋出事件是在UI執行緒中釋出, 那麼事件處理函式會在新的執行緒中執行, 如果釋出事件本來就在子執行緒中釋出的, 那麼事件處理函式在釋出事件的執行緒中執行. 此事件處理函式不可以進行UI更新操作

    ThreadMode.POSTING

        事件處理和事件釋出在同一個執行緒中. 在事件處理函式中儘量避免執行耗時操作, 因為它會阻塞事件的傳遞, 有可能會引起ANR

    ThreadMode.ASYNC

        不管事件在哪個執行緒中釋出, 該事件處理函式都會在新建的子執行緒中執行. 事件處理函式中禁止UI更新操作

例項

    事件處理函式

@Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEventMain(FirstEvent firstEvent) {
    Log.d(TAG, "接收到的訊息.1.." + Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.ASYNC)
public void onMessageEventAsync(FirstEvent firstEvent) {
    Log.d(TAG, "接收到的訊息.2.." + Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onMessageEventBackground(FirstEvent firstEvent) {
    Log.d(TAG, "接收到的訊息.3.." + Thread.currentThread().getName());
}

@Subscribe(threadMode = ThreadMode.POSTING)
public void onMessageEventPosting(FirstEvent firstEvent) {
    Log.d(TAG, "接收到的訊息.4.." + Thread.currentThread().getName());
}

從UI執行緒中釋出事件

    釋出事件

send.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        EventBus.getDefault().post(new FirstEvent("在同一個執行緒中執行"));
    }
});

    輸出log

02-27 10:26:29.727 14358-14358/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.1..main
02-27 10:26:29.727 14358-14358/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.4..main
02-27 10:26:29.728 14358-14420/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.2..pool-1-thread-1
02-27 10:26:29.729 14358-14421/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.3..pool-1-thread-2

從子執行緒中釋出事件

    釋出事件

send.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                EventBus.getDefault().post(new FirstEvent("在同一個執行緒中執行"));
            }
        }).start();
    }
});

輸出log

02-27 10:30:45.027 14523-14541/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.3..Thread-799
02-27 10:30:45.027 14523-14541/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.4..Thread-799
02-27 10:30:45.027 14523-14542/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.2..pool-1-thread-1
02-27 10:30:45.036 14523-14523/com.quanzi.eventbusdemo D/SameThreadActivity: 接收到的訊息.1..main

EventBus粘性事件

    EventBus的粘性事件類似於廣播中的粘性廣播. 粘性廣播在實際開發中使用的比較少.粘性廣播中訂閱/解除訂閱和普通事件一樣, 但是在處理訂閱函式時需要添加註解 sticky = true

    處理粘性事件

 @Subscribe(threadMode = ThreadMode.MAIN,sticky = true)
    public void onDataSynEvent(FirstEvent event){
        Log.d(TAG,"sticky..." + event.getMsg() + "..." + Thread.currentThread().getName());
    }

    傳送粘性事件

 EventBus.getDefault().postSticky(new FirstEvent("粘性事件..."));

     移除粘性事件

        粘性廣播屬於常駐廣播, 如果不需要可以移除粘性事件

    EventBus.getDefault().removeStickyEvent(new FirstEvent());

        或呼叫移除所有粘性事件

    EventBus.getDefault().removeAllStickyEvents();

EventBus的優缺點

    優點 : 簡化了各元件間的通訊方式, 實現瞭解耦讓業務程式碼更加簡潔, 可以動態設定事件處理執行緒以及優先順序

    缺點 : 每一個事件必須自定義一個事件類, 造成事件類過多, 從而增加了維護的成本

EventBus3.0與2.X比較

1.程式碼更加簡潔

2.效能更優. 由於EventBus 2.x 是採用反射的方式對整個註冊類中的所有方法進行掃描來完成註冊,因此在效能上有所影響。而EventBus3.0提供EventBusAnnotationProcessor註解處理器在編譯期通過讀取Subscribe註解並解析、處理其中所包含的資訊,再生成java類來儲存所有訂閱者的資訊,從而比在執行時使用反射來獲得這些訂閱者的資訊速度要快

以上是我個人對EventBus3.0的一些認識和理解,要是有什麼地方不對的,歡迎各位同仁指正

相關推薦

訊息傳遞機制EventBus的使用詳細

 EventBus是怎樣管理事件匯流排的, 是不是最佳處理訊息的方案?讓我們一同來學習和認識.EventBus由來    在面對應用程式內元件間, 元件與後臺執行緒間的通訊. 又如我們在處理耗時操作時, 等到耗時操作完成後通過Handler或者Broadcast去更新UI,

訊息傳遞機制元件之間訊息傳遞

通常在元件之間傳遞訊息,我們會採用廣播形式 , 自定義介面形式 , EventBus來實現BroadCastReceiver建立廣播private BroadcastReceiver receiver = new BroadcastReceiver() { @Over

Python GUI程式設計訊息傳遞機制&使用者登入

PythonGUI程式設計之-訊息傳遞機制及簡單的使用者登入 訊息機制 1.訊息的傳遞機制 自動發出事件/訊息 訊息由系統負責傳送到佇列 有相關元件進行繫結/設定 後端自動選擇感興趣的事件並作出相應的

Android訊息傳遞機制分析

1.事件響應機制的預備知識 在深入瞭解Android事件響應機制前,一些預備知識我們應該有所瞭解。 1.1 onTouch是優先於onClick執行,事件傳遞的順序是先經過onTouch,再傳遞到onClick。 1.2 Android中的事件onClick、onLon

【Android 開發】: Android 訊息處理機制四: Android 訊息迴圈 Looper 及其原始碼解析

  上一講我們學習Handler和Message的一些使用方式,我們知道Handler它會發送訊息和處理訊息,並且關聯一個子執行緒,如何傳送訊息入隊和出隊處理訊息等這些都是交給Looper去管理分發的,也就是它是負責整個訊息佇列運轉的一個類,這一講我們就來學習一下Andr

【Android 開發】: Android 訊息處理機制三: Handler 中 sendMessage() 原始碼剖析

  閱讀此文,請先閱讀以下相關連線: sendMessage()的幾種過載方法的使用方式的不同以及它們的原始碼的剖析.   通過前面幾講的內容,我們知道Android不但可以使用非同步任務處理多執行

Handler訊息傳遞機制(子執行緒中傳遞new Handler和主執行緒中new Handle傳遞訊息

> 子執行緒中更新UI new Thread(new Runnable() {         @Override         public void run() {             Looper.prepare();          

Handler訊息傳遞機制(一)簡介

宣告:本教程不收取任何費用,歡迎轉載,尊重作者勞動成果,不得用於商業用途,侵權必究!!! 文章目錄 前言簡介 實戰案例 1、在新啟動的子執行緒傳送訊息 2、在主執行緒中獲取、處理訊息 3、我的demo 和 演示效果 前言簡介 Android的訊息傳遞機制主要是

訊息傳遞機制(通訊)

一 同步和非同步(執行緒) 在維基百科中的釋義是:在計算機程式設計中,非同步,指的是獨立於主程式流發生的事件,以及處理該事件的方式。這些可能是“外部”事件,例如訊號的到達,或由程式發起的操作,該操作與程式同時/併發的執行,而程式不需要阻塞的等待結果。非同步的輸入(input)/輸出(outp

Windows訊息響應機制三:執行緒與訊息佇列

當一個執行緒第一次被建立時,系統假定執行緒不會用於任何與使用者相關的任務。這樣可以減少執行緒對系統資源的要求。但是,一旦該執行緒呼叫一個與圖形使用者介面有關的函式 ( 如檢查它的訊息佇列或建立一個視窗 ),系統就會為該執行緒分配一些另外的資源,以便它能夠執行與使用者介面有關

Windows訊息響應機制四:PostQuitMessage和GetMessage函式

 Windows是訊息驅動的作業系統。在Windows環境下程式設計必須熟練掌握Windows訊息響應機制。  今天在練習Win32程式設計時碰到一個關於GetMessage函式的問題。這個問題之前一直沒有引起過我的注意,但是今天  在網上搜索發現這個問題很多程式設計師都跟

Handler訊息傳遞機制(一)理解到底為什麼?

1.為什麼UI更新要在主執行緒中,主執行緒有什麼原則? 我們都知道,要在非UI執行緒更新UI需要使用到Handler或者AsyncTask(內部也是Handler實現),那麼為什麼就不能直接在子執行緒中更新UI,而要在UI執行緒中更新。這就扯到一個單執行緒和多

Android 多執行緒程式設計:Handler訊息傳遞機制—重新整理UI主介面

一、為什麼使用Handler   當一個Activity執行的時候,會開啟一條主執行緒,主執行緒主要負責處理與UI相關的事件,主執行緒不允許其他子執行緒操控它,更新UI介面。既然不允許我們在子執行緒中操控UI介面,那麼,像我們平時所見的點選獲取驗證碼,不斷更新

Handler訊息傳遞機制(三)Message訊息的兩種傳送方式

這裡佈局和mainfest的定義省了,直接看樣例 package com.example.message2; import android.app.Activity; import android

理解訊息傳遞機制訊息轉發機制

訊息傳遞機制 在物件上傳遞方法叫做“傳遞訊息”(pass a message)。訊息有“名稱”(name)或“選擇子”(selector),可以接受引數,而且可能還有返回值。 在Object-c中,如果向物件傳遞訊息,那就會使用動態繫結機制來決定需要呼叫的方

RabbitMQ實戰-訊息確認機制訊息的正確消費

上節中我們講了如何確保訊息的準確釋出,今天我們來看看如何確保訊息的正確消費。 在之前的基礎上我們對消費者(倉庫服務)進行完善。 修改配置檔案application.yml 消費者的ack方式預設是自動的,也就是說訊息一旦被消費(無論是否處理成功),訊息都會被確認,然後會從

九、rabbitMQ的訊息確認機制事務機制

說明:在rabbitMQ中,我們為了解決伺服器異常導致資料丟失的問題,我們可以採用rabbitMQ的持久化機制,但是我們如何確定生產者將訊息傳送給了rabbitMQ呢,那麼我們採用兩種協議的模式。    (1)、AMQP實現了事務機制    (2)、confirm模式一、事務

Android訊息傳遞機制---Handler,MessageQueue,Looper.

1.Android訊息機制概述以及背景 (1)Looper、Handler、Messagequeue三者共同實現了android系統裡執行緒間通訊機制。 如在A、B兩個子執行緒之間需要傳遞訊息,首先

引數傳遞機制JWT

1. 什麼是 JWT JWT 其全稱為:JSON Web Token,簡單地說就是 JSON 在 Web 上的一種帶簽名的標記形式。官方的定義如下: JSON Web Tokens are an open, industry standard RFC 7519 method for representing

windows訊息機制與ASP.net winform控制元件訊息傳遞滑鼠點選click事件

window系統是一個訊息驅動的系統, windows作業系統本身有自己的訊息佇列,訊息迴圈,它捕捉鍵盤,滑鼠的動作生成訊息,並將這個訊息傳給應用程式的訊息佇列。 當用戶用滑鼠click桌面時,其實使用者是不能直接接觸到某個控制元件的。表面上看,的確是使用者用