大家好我是程序员天天困。今天聊一个能让你少写一大堆回调的东西——EventBus一个在 Android 和 Java 里都挺火的事件发布订阅库。我自己做后端多一些但这东西在 Android 用得最广所以咱们两边都照顾着讲争取你写哪端都能用得上。话不多说直接开始。一、EventBus 到底是干什么的EventBus 不是什么新发明它就是把「发布-订阅」模式做成一个开箱即用的总线让两个模块不用互相认识就能通信。EventBus发布订阅事件总线greenrobot 出品的开源库用发布-订阅模式解耦组件通信——发布者只管把事件丢进总线订阅者通过注解方法接收两者互不持有引用。你可以把它理解成「代码里的广播站」。广播站的比喻最贴切拿话筒的人喊一嗓子所有调到这个频道的接收器都能听到喊的人根本不用知道谁在听。回到后端你写 Spring 时用过的EventListener配ApplicationEventPublisher或者 Guava 的EventBus乃至 Kafka、RabbitMQ都是同一套发布订阅思想的不同重量级实现。EventBus 是其中最轻的一个一个约 60k 的 jar不依赖任何中间件在进程内同步或异步分发延迟在微秒级。它的运行机制简单到一句话发布者调post把事件丢进 EventBusEventBus 根据事件类型查到所有订阅了这个类型的方法依次调用。就这么直接发布者不关心谁来收订阅者也不关心谁发的。二、为什么需要它组件通信的痛那有人就会问了Android 自己不是有通信机制吗为啥还要再造一个 EventBus这得先看看原生的那套东西痛在哪。Android 想让组件之间传消息最常用的就两样Handler 和 BroadcastReceiver。Handler 用来切线程、投递消息BroadcastReceiver 用来发系统级广播。能用是能用但写起来烦——一堆样板代码不说发消息的还得知道收消息的是谁两边经常要互相持有引用组件一多引用关系就缠成一团。最常见的场景你在子线程里跑接口请求数据回来要刷新 UI得拿 Handler 切回主线程两个 Fragment 要互换数据得借 Activity 当中间人或者写个 Listener 接口回调。项目小的时候忍忍就过去了业务一膨胀这种回调套回调、引用套引用的写法代码量和耦合度一起失控。后端其实一个毛病——Service 之间互相Autowired最后织成一张谁也拆不动的网根子都是发布者把「我要通知谁」写死在了自己代码里。EventBus 的解法很简单A 不认识 B/C/D它只认识 EventBus。谁关心谁自己订阅发布者彻底从「通知谁」里解放出来新增一个订阅者发布者一行代码都不用改。下面这张图把两种方式摆在一起——左边是组件之间互相持有引用、回调层层传递右边是发布者只对总线 post订阅者各自从总线取谁也不认识谁。可能有人会问那我后端直接上 Kafka、RabbitMQ 不就完了为啥还要一个进程内的 EventBus两者解决的不是同一个量级的问题。MQ 是跨进程、跨机器的异步消息带持久化和集群EventBus 是单进程内的方法调用级通信没有网络、没有序列化开销延迟在微秒级。同一个 JVM 内部模块解耦上 MQ 是杀鸡用牛刀跨服务通信EventBus 又鞭长莫及。各管一段别混用。三、三步上手在 Spring Boot 里用 EventBusEventBus 的全部 API 浓缩成三步——定义事件、注册订阅、发送事件背下来就能用。它不绑 AndroidSpring Boot 后端一样能跑把依赖换成eventbus-java就行。如果你团队已经定了用 EventBus或者要和 Android 端共用一套事件模型下面这套 Spring Boot 写法直接抄至于要不要在 Spring 里上它选型建议放在第六节。第一步引入 Maven 依赖。在pom.xml里加这一段!-- 以 Maven Central 3.3.1 为准Spring Boot 2.x 注解用 javax3.x 用 jakarta --dependencygroupIdorg.greenrobot/groupIdartifactIdeventbus-java/artifactIdversion3.3.1/version/dependency第二步定义事件 写订阅者。事件就是一个普通 POJO不继承任何基类订阅者用Subscribe标注接收方法方法必须 public、有且仅有一个参数publicclassLoginEvent{privatefinalStringusername;publicLoginEvent(Stringusername){this.usernameusername;}publicStringgetUsername(){returnusername;}}ComponentpublicclassUserModule{Subscribe(threadModeThreadMode.POSTING)publicvoidonLogin(LoginEventevent){System.out.println(用户 event.getUsername() 已登录);}PostConstruct// Bean 启动时注册publicvoidinit(){EventBus.getDefault().register(this);}PreDestroy// Bean 销毁时注销publicvoiddestroy(){EventBus.getDefault().unregister(this);}}把订阅者声明成 Spring 的Component再用PostConstruct注册、PreDestroy注销register 和 unregister 就跟着 Bean 生命周期自动成对不用你手动记着去调。第三步发送事件。在任何 Service 里直接 post发布者完全不需要知道谁在监听ServicepublicclassLoginService{publicvoidlogin(Stringusername){// 业务处理……EventBus.getDefault().post(newLoginEvent(username));}}我见过太多线上 OOM根因就是register了却没unregister——EventBus 持有订阅者引用对象回收不掉。所以哪怕图省事也务必让注册和注销跟着生命周期走别只 register 不注销。下面这张时序图展示了从post到被订阅方法处理的完整链路发布者 post 后EventBus 按事件类型查订阅表再按线程模式决定同步直调还是丢进线程池。四、Subscribe 三个关键参数线程模式、粘性事件、优先级Subscribe注解的三个参数不是花架子它们决定了事件在哪个线程跑、能不能收到「早到」的事件、谁先收到。SubscribeEventBus 的订阅方法注解标注「这个方法要接收什么类型的事件」可指定线程模式、是否粘性、优先级。被注解的方法要求 public 修饰、有且仅有一个参数。粘性事件Sticky EventpostSticky发出后会被 EventBus 缓存下来的事件之后新注册的订阅者也能收到它。你可以理解成「迟到的订阅者也能拿到上一条广播」。线程模式ThreadMode决定了订阅方法在哪个线程被执行。纯 Java 后端主要用 POSTING 和 ASYNCMAIN 系列依赖 Android 主线程后端用不到ThreadMode在哪执行纯 Java 能用典型场景POSTINGpost 所在线程直接同步调用能不耗时的事件最常用ASYNC永远丢进线程池异步执行能订阅者要做耗时 IOBACKGROUNDpost 在主线程则入池在子线程则直接调能轻量后台任务MAINAndroid 主线程执行否更新 UIMAIN_ORDERED主线程按顺序非阻塞否多个 UI 更新串行粘性事件有个坑要单独说缓存的粘性事件不会自动消失重复postSticky同类型会覆盖旧的但如果你忘了removeStickyEvent换场景后新订阅者可能收到一条本不该收的「历史事件」。我的习惯是粘性事件用完立刻removeStickyEvent别让缓存兜着脏数据。优先级priority是个 int数字越大越先收到且只在同一线程模式下才有意义。五、什么场景下用 EventBusEventBus 适合「一对多、发布者不想知道订阅者是谁」的场景不适合「调用方需要返回值」或「强顺序依赖」的场景。后者本质上是在做方法调用硬套事件总线只会让链路更难追踪。几类典型场景全局状态广播登录登出、网络断连恢复——一处 post多处 UI 或模块各自响应。跨层组件通信Fragment 之间、Fragment 与 Activity、Service 与页面不再借 Activity 中转。后端模块解耦领域事件的轻量版——下单成功后通知积分、库存、推送模块各自处理下单服务不关心下游有谁。配置热更新配置中心拉到新值后 post 一个ConfigChangedEvent各模块自己刷新。可能有人会问后端真要用 EventBus 吗还是直接 SpringEventListener更香老实说纯 Spring 后端我更推荐用 Spring 自带的EventListener零额外依赖、和容器生命周期天然集成、还支持TransactionalEventListener跟着事务走。EventBus 的甜区在 Android 和非 Spring 的纯 Java 工程——没有 Spring 容器、又想要个轻量发布订阅它比手撸观察者模式省心。要是跨进程老老实实上 MQ。六、后端视角的取舍EventBus vs Guava vs Spring选哪个看你在不在 Spring 容器里、要不要跨进程、对依赖体积多敏感。方案依赖线程模型跨进程适合谁greenrobot EventBus~60k jarThreadMode 五种否Android / 非 Spring 纯 JavaSpring 里也能跑Guava EventBusGuava 整包同步或异步二选一否已用 Guava 的纯 Java 项目Spring EventListenerSpring 容器同步可配异步否任何 Spring 后端Kafka / RabbitMQ独立中间件异步是跨服务、跨进程EventBus 也不是银弹几个老问题一直都在事件类会越定义越多一个项目几十个 Event 类很常见订阅方法靠反射查找编译时索引能优化但要配 annotation processor忘了unregister就内存泄漏最麻烦的是事件流难追踪——post一条事件到底谁会响应、什么顺序得全局搜调试链路偏长。这些都是它换来解耦的代价。写法上以 Maven Central 的org.greenrobot:eventbus:3.3.12021 年最后大版本为准长期稳定。Android 新项目也有人用 Kotlin 的 Flow / Channel 替代但就「最快上手、几行解耦」而言EventBus 依然是门槛最低的方案之一。后端要不要上 EventBus我的判断就一句在 Spring 里别折腾EventListener已经够用写 Android 或纯 Java 又想轻量解耦EventBus 依然是几行代码搞定、最省心的那个。跨进程的事交给 MQ别让一条进程内总线去干它不该干的活。
欧米茄官方保养价格查询|网点地址与客服热线权威信息公告(2026年7月最新) - 欧米茄官方服务中心 欧米茄官方保养价格查询与网点地址及客服热线权威信息公告(2026年7月最新)正式发布。这份公告整合了欧米茄全国唯一的统一客户服务体系的全部核心数据,涵盖官方售后渠道、服务项目收费标准、质保政策、技术标准以及…
2026年湖南Aigc培训机构推荐排行榜单汇总 - 互联网科技品牌测评 据行业公开统计,2025年国内AIGC内容产业相关岗位招聘量同比提升127%,相关技能培训的市场报名规模同比上涨92%。 湖南作为国内视频文创产业集聚地,马栏山文创园相关企业AIGC人才需求占比位列中部省份前列,本地对应的…
role仓库之Galaxy Ansible Galaxy 是官方统一角色仓库平台:https://galaxy.ansible.com 类似于GitHub,我们可以在这个平台上搜索别人写好的roles,然后下载到本地使用。 核心命令: 在线搜索 nginx 相关角色 ansible-galaxy search nginx 查看角色详情…
Unity性能优化全攻略:从核心概念到移动端实战调优 1. 项目概述:从入门到优化,一个Unity开发者的必经之路刚接触Unity引擎时,我们往往被它强大的可视化编辑器和“一次开发,多平台发布”的愿景所吸引。从导入第一个模型、编写第一行C#脚本控制角色移动开始,我们沉浸在创造…
Unity 2021.3兼容性实战:XUnity.AutoTranslator插件问题诊断与修复指南 1. 项目概述:当自动翻译插件遇上新版引擎如果你是一个Unity开发者,或者是一个热衷于体验各类独立游戏的玩家,那么“XUnity.AutoTranslator”这个名字对你来说可能并不陌生。这是一个在Unity游戏社区里颇具人气的运行时文本翻译插件࿰…
电赛ti板例程10+8学习 2026-07-19 电赛TI板例程108学习:从GPIO输入到定时器中断 一、今日目标跑通例程10(keyscan),理解GPIO输入、按键消抖、轮询检测 跑通例程8(systick),理解定时器中断、非阻塞延时、软件分频 建立…
基于springboot党建工作考评系统 一、关键词党建工作考评系统、党建工作考评、党建工作考评信息管理、党建工作考评后台管理二、作品包含源码数据库全套环境和工具资源本地部署教程三、项目技术前端技术: Html、Css、Js、Vue3.2、Element-Plus后端技术:Java、SpringBoot3.3.0、MyBatis-P…
用 curl 测试私有部署模型联通性 先检查服务健康状态 笔者通常会先访问健康检查接口,确认两个服务端口是否可达: curl -i http://[已脱敏IP]:8000/health curl -i http://[已脱敏IP]:8002/health 这里可以先把关注点放在两件事上:一是地址 http://[已脱敏IP] 是否能访问&…
NESBox模拟器:如何在浏览器中重温经典游戏怀旧体验? NESBox模拟器:如何在浏览器中重温经典游戏怀旧体验? 【免费下载链接】emulator Emulator of NES, Super Nintendo, Sega Mega Drive, GameBoy video consoles 项目地址: https://gitcode.com/gh_mirrors/em/emulator 你是否曾经想过在浏览器中直接…
2026 WAIC:努比亚二代“豆包手机”NaviX Ultra亮相,智能体验全面升级! 7月18日智东西消息,在2026 WAIC期间,努比亚联合字节豆包打造的二代“豆包手机”努比亚NaviX Ultra首次亮相,相比一代有诸多升级。智能体手机理念中兴通讯终端事业部总裁、努比亚总裁倪飞表示,智能体手机要从人操作手机变为手机帮人…
努比亚NaviX Ultra亮相WAIC,智能体手机能否让用户生活更简单? 努比亚NaviX Ultra:外观与功能双升级在2026 WAIC期间,首次亮相的努比亚NaviX Ultra吸引了众多目光。它是努比亚联合字节豆包打造的二代“豆包手机”,与一代努比亚M153相比,外观设计变化较大。其机身背部搭载横向排布的大尺寸影像模…
C# 将逗号分割的字符串转换为long,并添加到List<long> 目录 方法1:使用Split和Convert.ToInt64 方法2:使用LINQ的Select和ToList 方法3:使用TryParse进行异常安全转换(推荐) 如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天…
2026年7月最新太原百达翡丽官方售后客服电话及服务网点地址查询 - 百达翡丽官方售后中心 2026年7月,百达翡丽在太原的官方售后服务体系完成更新,客户可通过全国统一客服热线与服务网点获得直接、合规的腕表养护与维修支持。所有售后服务均遵循品牌直营标准,覆盖全国范围,客户可选择到店或邮寄方式,但需…
【JVM调优实战】16-可视化利器-JConsole-VisualVM-JMC 可视化利器:JConsole、VisualVM、JMC 实战 本文是《JVM调优实战》专栏第 16 讲。 引言 上一讲我们介绍了 JDK 命令行工具箱,它们轻量、快速,但有一个明显的短板:不直观。面对 jstat -gcutil 输出的一行行数字,你能感知 GC 频率,却难以一眼看出内存泄漏的趋势;你能用 js…
什么是PCTFE?医药高端包装的“防潮王牌“材料 ——日氟荣高分子材料(上海)有限公司 专业深耕氟材料领域很多人好奇,高端药品包装为什么比普通包装更防潮、更稳定、保质期更长?核心秘密,就藏在一种特种氟材料——PCTFE聚三氟氯乙烯里!作为国内领先的氟材…
[C++]内存管理:串顺序存储的内存回收 在串(字符串)的顺序存储中,内存回收的方式取决于字符串的存储方式以及所使用的编程语言和相关库。以下以 C 为例进行说明,因为 C 对内存管理有较为直接的控制。 1. 基于 char 数组的串顺序存储 如果使用普通的 char 数组来存储字…
移动端游戏功耗测试实战:电流、功率、亮度和场景对比 移动端游戏功耗测试:先控制变量,再比较优化是否真的省电 摘要:功耗测试最容易犯的错误,是拿两次不同温度、不同亮度、不同场景的平均功率直接比较。本文给出一套可复现的游戏功耗测试方法,覆盖引擎特性验证、版本回归和黑盒体验测试,并说明如何把功耗与帧率、温控、CPU/G…
足球口袋教练 HarmonyOS 离线应用实战(03/20):ArkUI 首页仪表盘搭建 本文是“足球口袋教练 HarmonyOS 离线应用实战”系列第 3 篇。示例项目是一个 HarmonyOS / ArkTS / ArkUI 编写的离线足球训练助手,围绕真实页面、真实截图和可复现操作展开。 本篇要解决的问题 训练 App 的首页不能只展示欢迎语,它要解决“我现在该点哪…