【Android】使用EventBus進行線程間通訊

EventBus

簡介

EventBus:github

EventBus是Android和Java的發布/訂閱事件總線。

  • 簡化組件之間的通信
    • 解耦事件發送者和接收者

    • 在 Activities, Fragments, background threads中表現良好

    • 避免復雜且容易出錯的依賴關系和生命周期問題

Publisher使用post發出一個Event事件,Subscriber在onEvent()函數中接收事件。
EventBus 是一款在 Android 開發中使用的發布/訂閱事件總線框架,基于觀察者模式,將事件的接收者和發送者分開,簡化了組件之間的通信,使用簡單、效率高、體積小!下邊是官方的 EventBus 原理圖:

導入

Android Projects:

implementation("org.greenrobot:eventbus:3.2.0")

Java Projects:

implementation("org.greenrobot:eventbus-java:3.2.0")
<dependency><groupId>org.greenrobot</groupId><artifactId>eventbus-java</artifactId><version>3.2.0</version>
</dependency>

配置

配置混淆文件

-keepattributes *Annotation*
-keepclassmembers class * {@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }# If using AsyncExecutord, keep required constructor of default event used.
# Adjust the class name if a custom failure event type is used.
-keepclassmembers class org.greenrobot.eventbus.util.ThrowableFailureEvent {<init>(java.lang.Throwable);
}# Accessed via reflection, avoid renaming or removal
-keep class org.greenrobot.eventbus.android.AndroidComponentsImpl

使用

簡單流程

  1. 創建事件類
public static class MessageEvent { /* Additional fields if needed */ }
  1. 在需要訂閱事件的地方,聲明訂閱方法并注冊EventBus。
@Subscribe(threadMode = ThreadMode.MAIN)  
public void onMessageEvent(MessageEvent event) {// Do something
}
public class EventBusActivity extends AppCompatActivity {@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);}@Overrideprotected void onStart() {super.onStart();//注冊EventBusEventBus.getDefault().register(this);}//接收事件@Subscribe(threadMode = ThreadMode.POSTING, sticky = true, priority = 1)public void onReceiveMsg(MessageEvent message){Log.e("EventBus_Subscriber", "onReceiveMsg_POSTING: " + message.toString());}//接收事件@Subscribe(threadMode = ThreadMode.MAIN, sticky = true, priority = 1)public void onReceiveMsg1(MessageEvent message){Log.e("EventBus_Subscriber", "onReceiveMsg_MAIN: " + message.toString());}//接收事件@Subscribe(threadMode = ThreadMode.MAIN_ORDERED, sticky = true, priority = 1)public void onReceiveMsg2(MessageEvent message){Log.e("EventBus_Subscriber", "onReceiveMsg_MAIN_ORDERED: " + message.toString());}@Overrideprotected void onDestroy() {super.onDestroy();//取消事件EventBus.getDefault().unregister(this);}
}
  1. 提交訂閱事件
@OnClick(R2.id.send_event_common)
public void clickCommon(){MessageEvent message = new MessageEvent(1, "這是一條普通事件");EventBus.getDefault().post(message);
}@OnClick(R2.id.send_event_sticky)
public void clickSticky(){MessageEvent message = new MessageEvent(1, "這是一條黏性事件");EventBus.getDefault().postSticky(message);
}

Subcribe注解

Subscribe是EventBus自定義的注解,共有三個參數(可選):threadMode、boolean sticky、int priority。 完整的寫法如下:

@Subscribe(threadMode = ThreadMode.MAIN,sticky = true,priority = 1)
public void onReceiveMsg(MessageEvent message) {Log.e(TAG, "onReceiveMsg: " + message.toString());
}

priority

priority是優先級,是一個int類型,默認值為0。值越大,優先級越高,越優先接收到事件。

值得注意的是,只有在post事件和事件接收處理,處于同一個線程環境的時候,才有意義。

sticky

sticky是一個boolean類型,默認值為false,默認不開啟黏性sticky特性,那么什么是sticky特性呢?

上面的例子都是對訂閱者 (接收事件) 先進行注冊,然后在進行post事件。

那么sticky的作用就是:訂閱者可以先不進行注冊,如果post事件已經發出,再注冊訂閱者,同樣可以接收到事件,并進行處理。

ThreadMode 模式

POSITING:訂閱者將在發布事件的同一線程中被直接調用。這是默認值。事件交付意味著最少的開銷,因為它完全避免了線程切換。因此,對于已知可以在很短時間內完成而不需要主線程的簡單任務,推薦使用這種模式。使用此模式的事件處理程序必須快速返回,以避免阻塞發布線程(可能是主線程)。

MAIN:在Android上,訂閱者將在Android的主線程(UI線程)中被調用。如果發布線程是主線程,將直接調用訂閱者方法,阻塞發布線程。否則,事件將排隊等待交付(非阻塞)。使用此模式的訂閱者必須快速返回以避免阻塞主線程。如果不是在Android上,行為與POSITING相同。

MAIN_ORDERED:在Android上,訂閱者將在Android的主線程(UI線程)中被調用。與MAIN不同的是,事件將始終排隊等待交付。這確保了post調用是非阻塞的。

BACKGROUND:在Android上,訂閱者將在后臺線程中被調用。如果發布線程不是主線程,訂閱者方法將在發布線程中直接調用。如果發布線程是主線程,EventBus使用一個后臺線程,它將按順序傳遞所有事件。使用此模式的訂閱者應盡量快速返回,以避免阻塞后臺線程。如果不是在Android上,總是使用一個后臺線程。

ASYNC:訂閱服務器將在單獨的線程中調用。這始終獨立于發布線程和主線程。使用此模式發布事件從不等待訂閱者方法。如果訂閱者方法的執行可能需要一些時間,例如網絡訪問,則應該使用此模式。避免同時觸發大量長時間運行的異步訂閱者方法,以限制并發線程的數量。EventBus使用線程池來有效地重用已完成的異步訂閱者通知中的線程。

/*** Each subscriber method has a thread mode, which determines in which thread the method is to be called by EventBus.* EventBus takes care of threading independently from the posting thread.* * @see EventBus#register(Object)* @author Markus*/
public enum ThreadMode {/*** Subscriber will be called directly in the same thread, which is posting the event. This is the default. Event delivery* implies the least overhead because it avoids thread switching completely. Thus this is the recommended mode for* simple tasks that are known to complete in a very short time without requiring the main thread. Event handlers* using this mode must return quickly to avoid blocking the posting thread, which may be the main thread.*/POSTING,/*** On Android, subscriber will be called in Android's main thread (UI thread). If the posting thread is* the main thread, subscriber methods will be called directly, blocking the posting thread. Otherwise the event* is queued for delivery (non-blocking). Subscribers using this mode must return quickly to avoid blocking the main thread.* If not on Android, behaves the same as {@link #POSTING}.*/MAIN,/*** On Android, subscriber will be called in Android's main thread (UI thread). Different from {@link #MAIN},* the event will always be queued for delivery. This ensures that the post call is non-blocking.*/MAIN_ORDERED,/*** On Android, subscriber will be called in a background thread. If posting thread is not the main thread, subscriber methods* will be called directly in the posting thread. If the posting thread is the main thread, EventBus uses a single* background thread, that will deliver all its events sequentially. Subscribers using this mode should try to* return quickly to avoid blocking the background thread. If not on Android, always uses a background thread.*/BACKGROUND,/*** Subscriber will be called in a separate thread. This is always independent from the posting thread and the* main thread. Posting events never wait for subscriber methods using this mode. Subscriber methods should* use this mode if their execution might take some time, e.g. for network access. Avoid triggering a large number* of long running asynchronous subscriber methods at the same time to limit the number of concurrent threads. EventBus* uses a thread pool to efficiently reuse threads from completed asynchronous subscriber notifications.*/ASYNC
}

相關文檔

  • EventBus詳解 (詳解 + 原理)
  • 三幅圖弄懂EventBus核心原理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/24182.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/24182.shtml
英文地址,請注明出處:http://en.pswp.cn/web/24182.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

好書推薦-人工智能數學基礎

本書以零基礎講解為宗旨&#xff0c;面向學習數據科學與人工智能的讀者&#xff0c;通俗地講解每一個知識點&#xff0c;旨在幫助讀者快速打下數學基礎。    全書分為 4 篇&#xff0c;共 17 章。其中第 1 篇為數學知識基礎篇&#xff0c;主要講述了高等數學基礎、微積分、泰…

鴻蒙Ability Kit(程序框架服務)【應用啟動框架AppStartup】

應用啟動框架AppStartup 概述 AppStartup提供了一種更加簡單高效的初始化組件的方式&#xff0c;支持異步初始化組件加速應用的啟動時間。使用啟動框架應用開發者只需要分別為待初始化的組件實現AppStartup提供的[StartupTask]接口&#xff0c;并在[startup_config]中配置App…

Open vSwitch 數據包處理流程

一、Open vSwitch 數據包轉發模式 Open vSwitch 根據不同的模塊使用&#xff0c;主要分為兩種數據包的轉發模式&#xff1a;Datapath 模式和 DPDK 模式&#xff0c;這兩種模式的主要區別在于&#xff1a; Datapath 模式&#xff1a; 使用內核空間的網絡棧進行數據包的轉發性能相…

理解和實現 LRU 緩存置換算法

引言 在計算機科學中&#xff0c;緩存是一種用于提高數據訪問速度的技術。然而&#xff0c;緩存空間是有限的&#xff0c;當緩存被填滿時&#xff0c;就需要一種策略來決定哪些數據應該保留&#xff0c;哪些應該被淘汰。LRU&#xff08;最近最少使用&#xff09;算法是一種廣泛…

UML實現圖-部署圖

概述 部署圖(Deployent Diagram)描述了運行軟件的系統中硬件和軟件的物理結構。部署圖中通常包含兩種元素:節點和關聯關系&#xff0c;部署圖中每個配置必須存在于某些節點上。部署圖也可以包含包或子系統。 節點是在運行時代表計算機資源的物理元素。節點名稱有兩種:簡單名和…

android studio開發時提示 TLS 握手錯誤解決辦法

我用的是windows&#xff0c;遇到了這錯誤&#xff0c; The server may not support the clients requested TLS protocol versions: (TLSv1.2, TLSv1.3). You may need to configure the client to allow other protocols to be used. For more on this, please refer to http…

蒼穹外賣筆記-08-套餐管理-增加,刪除,修改,查詢和起售停售套餐

套餐管理 1 任務2 新增套餐2.1 需求分析和設計接口設計setmeal和setmeal_dish表設計 2.2 代碼開發2.2.1 根據分類id查詢菜品DishControllerDishServiceDishServiceImplDishMapperDishMapper.xml 2.2.2 新增套餐接口SetmealControllerSetmealServiceSetmealServiceImplSetmealMa…

c++替換字符或字符串函數

在C中&#xff0c;有多種方法可以替換字符串或字符。下面是一些常用的方法&#xff1a; 使用replace函數&#xff1a; replace函數可以替換字符串中的指定字符或子字符串。它的用法如下&#xff1a; string str "Hello World"; str.replace(str.find("World&qu…

Nginx03-動態資源和LNMP介紹與實驗、自動索引模塊、基礎認證模塊、狀態模塊

目錄 寫在前面Nginx03案例1 模擬視頻下載網站自動索引autoindex基礎認證auth_basic模塊狀態stub_status模塊模塊小結 案例2 動態網站&#xff08;部署php代碼&#xff09;概述常見的動態網站的架構LNMP架構流程數據庫Mariadb安裝安全配置基本操作 PHP安裝php修改配置文件 Nginx…

AI做的2024年高考數學試卷,答案對嗎?

2024年高考數學考試已經結束&#xff0c;現在呈上數學真題及AI給出的解答。供各位看官欣賞。 總的來說&#xff0c;人工做題兩小時&#xff0c;AI解答兩分鐘。 但是&#xff0c;AI做的答案是否正確&#xff0c;那就要各位看官來評判了&#xff01; 注&#xff1a;試卷來源于…

【Linux】另一種基于rpm安裝yum的方式

之前的163的鏡像源504網關異常了&#xff0c;網上找到的方法基本都是基于apt&#xff0c;或是基于apt-get。找到了大佬幫忙裝了一下&#xff0c;記錄如下&#xff1a; wget https://vault.centos.org/7.9.2009/os/x86_64/Packages/yum-metadata-parser-1.1.4-10.el7.x86_64.rpm…

2024年5大制作AI電子手冊工具推薦

AI電子手冊作為一種結合了人工智能技術和傳統電子手冊功能的新型工具&#xff0c;逐漸成為了企業進行知識管理和信息傳遞的重要工具&#xff0c;為企業提高效率、優化用戶體驗。在本文中&#xff0c;LookLook同學將簡單介紹一下什么是AI電子手冊、對企業有什么好處&#xff0c;…

JAVA面試中,面試官最愛問的問題。

Optional類是什么&#xff1f;它在Java中的用途是什么&#xff1f; Java中的Optional類是一個容器類&#xff0c;它用于封裝可能為空的對象。在Java 8之前&#xff0c;空值檢查是Java編程中一個常見的問題&#xff0c;尤其是在處理返回單個值的方法時。Optional類提供了一種更…

電源變壓器的作用和性能

電源變壓器的主要作用是改變輸入電壓的大小&#xff0c;通常用于降低電壓或升高電壓&#xff0c;以便適應不同設備的需求。它們還可以提供隔離&#xff0c;使得輸出電路與輸入電路之間電氣隔離&#xff0c;從而提高安全性。性能方面&#xff0c;電源變壓器需要具有高效率、低溫…

Unity3D測量距離實現方法(一)

系列文章目錄 unity工具 文章目錄 系列文章目錄&#x1f449;前言&#x1f449;一、Unity距離測量1-1 制作預制體1-2 編寫測量的腳本 &#x1f449;二、鼠標點擊模型進行測量&#x1f449;二、字體面向攝像機的方法&#x1f449;二、最短距離測量方法&#x1f449;三、壁紙分享…

Python中的裝飾器鏈(decorator chain)是什么

在Python中&#xff0c;裝飾器是一種高級功能&#xff0c;它允許你在不修改函數或類代碼的情況下&#xff0c;為它們添加額外的功能。裝飾器通常用于日志記錄、性能測量、權限檢查等場景。當多個裝飾器應用于同一個函數或類時&#xff0c;它們會形成一個裝飾器鏈&#xff08;de…

Go語言中,公司gitlab私有倉庫依賴拉取配置

為什么要考慮私有倉庫 Go語言目前都已經采用了官方統一的 go modules 來管理依賴&#xff0c;后續也不太可能出現比較亂的生態&#xff0c; 因此了解下如何讓這個依賴管理正常工作是非常必要的。 對于Github或者其他公有倉庫&#xff0c;依賴管理是非常直接和方便的,設置好GO…

C++ 依賴的C庫查看和下載

依賴庫查詢&#xff1a;ldd 指令 # ldd libcyber.solinux-vdso.so.1 (0x0000ffff86b52000)libopt_proto.so > /home/caros/cyberrt/lib/libopt_proto.so (0x0000ffff84c4a000)libboost_filesystem.so.1.73.0 > /opt/orin/usr/local/lib/libboost_filesystem.so.1.73.0 (…

Java版工程項目管理平臺:以源碼驅動,引領工程企業數字化轉型

在當今數字化時代&#xff0c;隨著企業的擴張和業務的增長&#xff0c;傳統的工程項目管理方法已顯不足。為了提升管理效率、減輕工作負擔、增強信息處理的快速性和精確度&#xff0c;工程企業亟需借助數字化技術進行轉型升級。本文將向您展示一款基于Spring Cloud、Spring Boo…

SS2D反向傳播問題記錄【未解決】

使用SS2D寫了一個簡單的神經網絡進行訓練&#xff0c;但是訓練報錯&#xff1a; NotImplementedError: You must implement either the backward or vjp method for your custom autograd.Function to use it with backward mode AD. 環境&#xff1a; CUDA11.8 torch2.0.0 mam…