【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.mzph.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…