Android 消息发布订阅框架:EventBus

news2024/9/17 7:21:34

目录

1.是什么
2.如何使用
3.五种线程模型
4.Eventbus2和Eventbus3的区别

一、是什么

EventBus是一款发布/订阅事件总线的框架,使用它可以进行模块间通信、解耦。它可以使用很少的代码,来实现多组件之间的通信,非常的方便。

为什么使用它呢?以前一直在用广播来实现,但是广播使用起来较为麻烦且效率不高,当项目变大以后,就会变得特别复杂。LiveData也可以进行数据的订阅和发布,但是不能处理复杂的情况。我们可以使用EventBus。

EventBus是一种用于Android平台上的事件发布/订阅框架,它允许不同的组件之间进行松耦合通信,而不需要显式地注册监听器或调用回调接口。EventBus通过线程模型来控制事件处理函数的执行线程

核心流程就是:EventBus通过使用post方法发出一个Event事件,然后定义一个onEvent()方法,在里面接收事件并进行处理。

二、如何使用呢?

  1. 依赖
implementation("org.greenrobot:eventbus:3.3.1")
  1. 定义事件 (Event)
//事件是pojo对象,没有如何特定的要求
data class MessageEvent(
    val message:String
)
  1. 准备订阅者:也就是接收处理的。(Subscriber)
class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
       
        startService(Intent(this,MyService::class.java))
//        EventBus.getDefault().post(MessageEvent("Hello everyone!"));自己发送,自己收不到的。

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onMessageEvent(event:MessageEvent){
        //toast被调用时,会在主线程。
        Toast.makeText(this,event.message,Toast.LENGTH_LONG).show()
    }

//    @Subscribe
//    fun handleSomethingElse(event: MessageEvent?) {
//    }
}

(1)@Subscribe(threadMode = ThreadMode.MAIN),用来决定这个方法是在什么线程执行。
订户还需要 在总线上注册 themselves to 和取消注册 。只有当订阅者注册时,他们才会收到事件。在 Android 中,在活动和片段中,您通常应 根据其生命周期进行注册。在大多数情况下,onStart/onStop 工作正常:

    override fun onStart() {
        super.onStart()
        EventBus.getDefault().register(this);
    }

    override fun onStop() {
        EventBus.getDefault().unregister(this);
        super.onStop()

    }
  1. 发布事件(Publisher)
class MyService : Service() {
    override fun onBind(p0: Intent?): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        EventBus.getDefault().post(MessageEvent("Hello everyone!"));
    }
}

Subscribe

  1. 一个Subscribe可以对应多个Event ,也就是说我们可以监听不同的事件,多写几个onMessageEvent方法,
  2. EventBus3.0 开始用Subscribe注解配置事件订阅方法,不再使用方法名 ,有这个注解就会自动找到这个方法。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface Subscribe {
    // 指定事件订阅方法的线程模式,即在那个线程执行事件订阅方法处理事件,默认为POSTING
    ThreadMode threadMode() default ThreadMode.POSTING;
    // 是否支持粘性事件,默认为false,sticky的作用就是:订阅者可以先不进行注册,如果post事件已经发出,再注册订阅者,同样可以接收到事件,并进行处理。
    boolean sticky() default false;
    // 指定事件订阅方法的优先级,默认为0,如果多个事件订阅方法可以接收相同事件的,则优先级高的先接收到事件
    int priority() default 0;
}

Publisher

  1. EventBus.getDefault()方法是一个单例。
  2. register()方法进行注册:会在当前要注册的类以及其父类中查找订阅事件的方法 ,到时候进行事件调用。unregister为取消注册。
  3. post()方法进行事件发送。

三、五种线程模型

MAIN
● 行为:无论事件在哪个线程发布,事件处理函数都会在主线程(UI线程)中执行。
● 适用场景:适用于需要更新UI的场景,因为UI更新必须在主线程中进行。
● 注意:事件处理的时间不能太长,长了会导致ANR。

BACKGROUND
● 行为:如果事件是在主线程中发布的,那么事件处理函数将在后台线程中执行;如果事件是在后台线程中发布的,则直接在发布线程中执行。
● 适用场景:适用于执行耗时操作且不需要在主线程中执行的场景。
● 注意:在此事件处理函数中禁止进行UI更新操作。

ASYNC
● 行为:无论事件在哪个线程发布,事件处理函数都会在新建的子线程中执行。
● 适用场景:适用于执行耗时操作且不需要关心具体在哪个线程中执行的场景。
● 注意:同样,在此事件处理函数中禁止进行UI更新操作。

POSTING
● 行为:事件在哪个线程发布,就在哪个线程处理。这是EventBus的默认线程模式,避免了线程切换,效率高。
● 适用场景:适用于不需要在主线程执行,且耗时很短的简单任务。
● 注意:在POSTING模式的事件处理函数中尽量避免执行耗时操作,因为它会阻塞事件的传递,甚至有可能会引起ANR(应用无响应)。

MAIN_ORDERED
● 行为: 确保事件处理函数在主线程(UI线程)中调用,并且这些事件将按照它们被发布的顺序排队等待处理。这意味着,即使事件是在主线程中并发发布的,它们也会按照发布的顺序被处理,而不会打乱。此外,与MAIN模式不同的是,MAIN_ORDERED模式中的事件处理函数会在一个事件队列中等待,直到它们被按顺序处理。
● 适用场景:当需要保证事件处理的顺序时,可以使用此模式。
● 注意:与MAIN模式一样,事件处理的时间也不能太长,否则会导致ANR。

四、Eventbus2和3的区别

  1. 回调方法命名与注解

    EventBus 2:在EventBus 2中,接收事件的方法名需要使用约定的命名规则,例如onEvent、onEventAsync、onEventBackground、onEventMainThread等,通过方法名来判定是否是接收事件的方法以及事件处理的线程模式。
    EventBus 3:在EventBus 3中,接收事件的方法名可以随意命名,但需要通过@Subscribe注解来指定事件处理的方法,并通过注解中的threadMode属性来指定事件处理的线程模式。这种方式提供了更大的灵活性,并且使得代码更加清晰和易于维护。

  2. 线程模型的默认值和多样性

    EventBus 2:线程模型主要通过方法名来区分,如onEventMainThread表示在主线程处理,onEventAsync表示在异步线程处理等。
    EventBus 3:引入了更多的线程模型选项,包括POSTING(默认,与发布事件的线程相同)、MAIN(在主线程处理)、MAIN_ORDERED(在主线程按顺序处理)、BACKGROUND(在后台线程处理)和ASYNC(在异步线程处理)。在未声明threadMode时,EventBus 3默认使用POSTING模式。

  3. 异常处理

    EventBus 3:在EventBus 3中,如果在@Subscribe标注的方法中程序出错,不会程序崩溃,而是由EventBus拦截异常,并打印错误日志。这有助于避免因为单个事件处理失败而导致整个应用崩溃的情况。

  @Subscribe(threadMode = ThreadMode.MAIN)
   fun onMessageEvent(event:MessageEvent){
       //toast被调用时,会在主线程。
       Toast.makeText(this,event.message,Toast.LENGTH_LONG).show()
       println(1/0)
   }

在这里插入图片描述

  1. 性能优化

    EventBus 3:EventBus 3通过利用编译时检索所有注解代码,并生成一个包含所有在运行时要花很大代价才能获取的数据的类,来提升性能。这种新的注解处理方式使得EventBus 3在性能上比EventBus 2有所提升。

eventbus的缺点有哪些?

性能问题

1.反射开销:EventBus在注册时会使用反射来遍历注册对象的方法,以找出带有@Subscribe注解的方法。这种反射操作在注册大量对象或复杂对象时可能会带来较大的性能开销。
2.对象创建:虽然EventBus 3.0开始使用了对象池缓存来减少创建对象的开销,但在高并发场景下,仍然需要关注对象的创建和销毁对性能的影响。

内存泄漏风险

1.问题描述:EventBus要求开发者在适当的时候进行注册和反注册操作。如果忘记在组件销毁时反注册EventBus,那么该组件及其相关的事件订阅者可能会因为EventBus的持有而无法被垃圾回收器回收,从而导致内存泄漏。
2.影响:内存泄漏会严重影响应用的性能和稳定性,甚至可能导致应用崩溃。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1940878.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安装caffe-CPU版本并进行训练

目录 前言 0、安装Ubuntu 18.04 版本 输入ls没有反应 ubuntu换源 换源出现的问题 1、安装caffe出现E:Unable to locate package caffe-cpu问题 2、把 code 文件夹下载到 ubuntu 3、在本地使用caffe-CPU,并部署数据标注工具 ATool 问题1 问题2 问题3 命令行…

C语言迷宫

目录 开头程序程序的流程图程序输入与输出的效果结尾 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我要来看我用C语言编译出来的迷宫游戏。 程序 #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <Windows.h> void printmaze(char s…

计算机网络基础:局域网、广域网及OSI七层模型解析

文章目录 一、局域网和广域网1、局域网&#xff08;LAN - Local Area Network&#xff09;2、广域网&#xff08;WAN - Wide Area Network&#xff09;3、对比局域网和广域网 二、OSI七层模型1、OSI的七层网络结构2、OSI的数据传输方式3、网络与操作系统的关系 一、局域网和广域…

“论系统安全架构设计及其应用”,写作框架,软考高级论文,系统架构设计师论文

论文真题 随着社会信息化进程的加快&#xff0c;计算机及网络已经被各行各业广泛应用&#xff0c;信息安全问题也变得愈来愈重要。它具有机密性、完整性、可用性、可控性和不可抵赖性等特征。信息系统的安全保障是以风险和策略为基础&#xff0c;在信息系统的整个生命周期中提…

【BUG】已解决:error: legacy - install - failure

error: legacy - install - failure 目录 error: legacy - install - failure 【常见模块错误】 【解决方案】 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页&#xff0c;我是博主英杰&#xff0c;211科班出身&#xff0c;就职于医疗科技公司&…

spring-boot 整合 redisson 实现延时队列(文末有彩蛋)

应用场景 通常在一些需要经历一段时间或者到达某个指定时间节点才会执行的功能&#xff0c;比如以下这些场景&#xff1a; 订单超时提醒收货自动确认会议提醒代办事项提醒 为什么使用延时队列 对于数据量小且实时性要求不高的需求来说&#xff0c;最简单的方法就是定时扫描数据…

sql常见50道查询练习题

sql常见50道查询练习题 1. 表创建1.1 表创建1.2 数据插入 2. 简单查询例题(3题&#xff09;2.1 查询"李"姓老师的数量2.2 查询男生、女生人数2.3 查询名字中含有"风"字的学生信息 3. 日期相关例题(6题&#xff09;3.1 查询各学生的年龄3.2 查询本周过生日的…

73、Flink 的 DataStream API 生产实践总结

0、汇总 1.可以使用 Maven 命令、CURL 命令、IDEA 手动创建 Flink 项目&#xff1b;2.可以使用 Maven Shade 插件将必需的依赖项打包进应用程序 jar 中&#xff1b;3.应该在 Flink 集群的 lib 文件夹内配置需要的&#xff08;核心&#xff09;依赖项&#xff1b;4.应该将程序中…

探索球形气膜的独特魅力:移动性与经济性的结合—轻空间

球形气膜结构因其独特的设计和多功能性而备受青睐。它不仅在空间利用方面有着显著优势&#xff0c;还展现出出色的移动性和经济性。以下是球形气膜的关键特点&#xff1a; 灵活的移动性 球形气膜以其轻便且易于移动的特性而闻名。这种结构设计使得气膜可以在不同场地之间快速组…

测试管理工具、自动化测试工具、跨浏览器测试工具 推荐

测试管理工具 1&#xff09;Xray Xray 是排名第一的手动与自动化测试管理应用&#xff0c;专为质量保证而设计。它是一个功能齐全的工具&#xff0c;能够无缝集成于 Jira 中。其目的是通过有效和高效的测试帮助公司提高产品质量。 功能特点&#xff1a; 需求、测试、缺陷和执…

Docker核心技术:容器技术要解决哪些问题

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 Docker核心技术 系列文章&#xff1a;容器技术要解决哪些问题&#xff0c;其他文章快捷链接如下&#xff1a; 应用架构演进容器技术要解决哪些问题&#xff08;本文&#xff09;Docker的基本使用Docker是如何实…

MySQL学习记录 —— 이십삼 MySQL服务器文件系统(3)

文章目录 1、数据字典2、系统表各种系统表 Mysql Schema是⼀个系统库&#xff0c;表中存储了MySQL服务器运行时所需的信息。广义上&#xff0c;mysql schema包含存储MySQL程序基本数据的数据字典和用于其他操作目的的系统表。数据字典表和系统表位于数据目录下一个名为mysql.ib…

Spring-Aop源码解析(二)

书接上文&#xff0c;上文说到&#xff0c;specificInterceptors 不为空则执行createProxy方法创建代理对象&#xff0c;即下图的createProxy方法开始执行&#xff0c;生成代理对象&#xff0c;生成代理对象有两种方式&#xff0c;JDK和CGLIB。 createAopProxy就是决定使用哪…

(ISPRS,2021)具有遥感知识图谱的鲁棒深度对齐网络用于零样本和广义零样本遥感图像场景分类

文章目录 Robust deep alignment network with remote sensing knowledge graph for zero-shot and generalized zero-shot remote sensing image scene classification相关资料摘要引言遥感知识图谱的表示学习遥感知识图谱的构建实体和关系的语义表示学习创建遥感场景类别的语…

【Git-驯化】手把手搭建Mac电脑中git环境配置以及连接github仓库

【Git-驯化】手把手搭建Mac电脑中git环境配置以及连接github仓库 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关…

【Linux】HTTP 协议

目录 1. URL2. HTTP 协议2.1. HTTP 请求2.2. HTTP 响应 1. URL URL 表示着是统一资源定位符(Uniform Resource Locator), 就是 web 地址&#xff0c;俗称“网址”; 每个有效的 URL 可以通过互联网访问唯一的资源, 是互联网上标准资源的地址; URL 的主要由四个部分组成: sche…

【MySQL-17】存储过程-[变量篇]详解-(系统变量&用户定义变量&局部变量)

前言 大家好吖&#xff0c;欢迎来到 YY 滴MySQL系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…

Pytorch使用前期准备

一、检查英伟达驱动和CUDA Toolkit是否正确安装 1.任务管理器性能选项卡中能正确显示显卡型号则表示显卡驱动正确安装 2. CUDA Toolkit会跟随pytorch自动安装 二、虚拟环境的准备 Miniconda — Anaconda documentationhttps://docs.anaconda.com/miniconda/ 1.安装anaconda或者…

Linux实用操作三

文章目录 Linux实用操作三网络传输ping命令介绍&#xff1a;示例&#xff1a; wget命令介绍&#xff1a;示例&#xff1a; curl命令介绍&#xff1a;示例&#xff1a; 端口介绍&#xff1a;端口的划分&#xff1a;查看端口占用&#xff1a; 进程管理进程介绍&#xff1a;查看进…

二十一、【机器学习】【非监督学习】- 谱聚类 (Spectral Clustering)​​

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…