Android 消息发布订阅框架:EventBus

目录

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.影响:内存泄漏会严重影响应用的性能和稳定性,甚至可能导致应用崩溃。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

十七、(正点原子)Linux LCD驱动

一、Framebuffer设备 在 Linux 中应用程序通过操作 RGB LCD 的显存来实现在 LCD 上显示字符、图片等信息。 先来看一下裸机 LCD 驱动如下: ①、初始化 I.MX6U 的 eLCDIF 控制器,重点是 LCD 屏幕宽(width)、高(height)、 hspw、 hbp、 hfp、 vspw…

go中map

文章目录 Map简介哈希表与Map的概念Go语言内建的Map类型Map的声明Map的初始化Map的访问Map的添加和修改Map的删除Map的遍历 Map的基本使用Map的声明与初始化Map的访问与操作Map的删除Map的遍历Map的并发问题实现线程安全的Map 3. Map的访问与操作3.1 访问Map元素代码示例&#…

微信小程序 button样式设置为图片的方法

微信小程序 button样式设置为图片的方法 background-image background-size与background-repeat与border:none;是button必须的 <view style" position: relative;"><button class"customer-service-btn" style"background-image: url(./st…

新华三H3CNE网络工程师认证—VLAN使用场景与原理

通过华三的技术原理与VLAN配置来学习&#xff0c;首先介绍VLAN&#xff0c;然后介绍VLAN的基本原理&#xff0c;最后介绍VLAN的基本配置。 文章目录 一、传统以太网问题1、广播域范围过大2、分割广播域 二、如何实现VLAN1、VLAN技术达到的效果2、VLAN数值的编号范围3、仿真&am…

这届打工人,快把单休卷成职场用工标配了……

最近&#xff0c;小柴有个朋友跟小柴吐槽&#xff0c;自己被「灵活就业」大半年了&#xff0c;有点扛不住&#xff0c;就准备去送外卖&#xff0c;结果第一天赚了38&#xff0c;反手电瓶车罚了50…… 心灰意冷的他&#xff0c;最终还是在某BOSS上充个值&#xff0c;没日没夜的投…

手持式气象站:便携科技,掌握微观气象的利器

手持式气象站&#xff0c;顾名思义&#xff0c;是一种可以随身携带的气象监测设备。它小巧轻便&#xff0c;通常配备有温度、湿度、风速、风向、气压等多种传感器&#xff0c;能够实时测量并显示各种气象参数。不仅如此&#xff0c;它还具有数据存储、数据传输、远程控制等多种…

搭建博客系统#Golang

WANLI 博客系统 项目介绍 基于vue3和gin框架开发的前后端分离个人博客系统&#xff0c;包含md格式的文本编辑展示&#xff0c;点赞评论收藏&#xff0c;新闻热点&#xff0c;匿名聊天室&#xff0c;文章搜索等功能。 点击跳转&#xff1a;Github 项目开源地址 功能展示 B 站…

实战篇(十):使用Processing创建可爱花朵:实现随机位置、大小和颜色的花朵

使用Processing创建可爱花朵 0.效果预览1. 引言2. 设置Processing环境3. 创建花朵类4. 实现花瓣绘制5. 绘制可爱的笑脸6. 鼠标点击生成花朵7. 完整代码8. 总结与扩展0.效果预览 在本教程中,我们将使用Processing编程语言来创建一个可爱的花朵生成器。通过封装花朵为一个类,并…

使用shedlock实现分布式互斥执行

前言 前序章节&#xff1a;springboot基础(82):分布式定时任务解决方案shedlock 如果你不清楚shedlock&#xff0c;建议先阅读前序章节&#xff0c;再来查看本文。 如果我们不在spring环境下&#xff0c;如何使用shedlock实现分布式互斥执行&#xff1f; 我们可以使用shedl…

Elasticsearch 7.x入门学习-Java API操作

1 创建项目 在idea开发工具中创建Maven项目 修改 pom 文件&#xff0c;增加 Maven 依赖关系 <dependencies><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.8.0</versi…

ubuntu2204配置anacondacuda4090nvidia驱动

背景 某个机房的几台机器前段时间通过dnat暴露至公网后被入侵挖矿&#xff0c;为避免一些安全隐患将这几台机器执行重装系统操作&#xff1b; 这里主要记录配置nvidia驱动及cuda&anaconda。 步骤 大概分为几个步骤 禁用nouveau配置grub显示菜单install nvidia-driveri…

Linux云计算 |【第一阶段】ENGINEER-DAY3

主要内容&#xff1a; LVM逻辑卷管理、VDO、RAID磁盘阵列、进程管理 一、新建逻辑卷 1、什么是逻辑卷 逻辑卷&#xff08;Logical Volume&#xff09;是逻辑卷管理&#xff08;Logical Volume Management&#xff0c;LVM&#xff09;系统中的一个概念。LVM是一种用于磁盘管理…

SpringBoot集成MQTT实现交互服务通信

引言 本文是springboot集成mqtt的一个实战案例。 gitee代码库地址&#xff1a;源码地址 一、什么是MQTT MQTT&#xff08;Message Queuing Telemetry Transport&#xff0c;消息队列遥测传输协议&#xff09;&#xff0c;是一种基于发布/订阅&#xff08;publish/subscribe&…

[Armbian] 部署Docker版Home Assistent,安装HACS并连接米家设备

title: [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 date: 2024-07-21T10:51:23Z lastmod: 2024-07-21T11:40:39Z [Armbian] 部署Docker版Home Assistent&#xff0c;安装HACS并连接米家设备 官网&#xff1a;Home Assistant (home-assistant.i…

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 查询本周过生日的…

Yolo-World网络模型结构及原理分析(一)——YOLO检测器

文章目录 概要一、整体架构分析二、详细结构分析YOLO检测器1. Backbone2. Head3.各模块的过程和作用Conv卷积模块C2F模块BottleNeck模块SPPF模块Upsampling模块Concat模块 概要 尽管YOLO&#xff08;You Only Look Once&#xff09;系列的对象检测器在效率和实用性方面表现出色…

【GraphRAG】微软 graphrag 效果实测

GraphRAG 本文将基于以下来源&#xff0c;对Microsoft GraphRAG分析优缺点、以及示例实测分析。 1. Source 代码仓库&#xff1a; Welcome to GraphRAGhttps://microsoft.github.io/graphrag/ 微软文章1&#xff08;2024.2.13&#xff09;&#xff1a;GraphRAG: Unlocking…

通过albumentation对目标检测进行数据增强(简单直接)

albumentation官方文档看不懂&#xff1f;xml文件不知道如何操作&#xff1f;下面只需要修改部分代码即可上手使用 要使用这个方法之前需要按照albumentation这个库还有一些辅助库,自己看着来安装就行 pip install albumentation pip install opencv-python pip install json…

阿尔泰科技利用485模块搭建自动灌溉系统实现远程控制

自动灌溉系统又叫土壤墒情监控系统&#xff0c;土壤墒情监控系统主要实现固定站无人值守情况下的土壤墒情数据的自动采集和无线传输&#xff0c;数据在监控中心自动接收入库&#xff1b;可以实现24小时连续在线监控并将监控数据通过有线、无线等传输方式实时传输到监控中心生成…

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…