如何使用EventBus?

概述

EventBus 是适用于 Android 和 JAVA 的发布/订阅事件总线。主要功能是替代 Intent、Handler、BroadCast 在 Activity、Fragment、Service 线程之间传递消息。EventBus 能够简化应用组件间的通信,解耦 (有效分离) 事件的发送者和接收者,避免复杂和容易出错的依赖和生命周期问题,开销小,代码更优雅。但是需要注意的是 EventBus 不能用于进程间通信。

特性

Andorid 组件间通信,可能都是用 Handler 消息机制或者广播机制来实现通信,但是它们代码量大,组件上容易产生耦合 。为什么选择使用 EventBus 来做通信?

  • 简化了组件间的通信
  • 对事件通信双方进行解耦
  • 在 Activity、Fragment 和后台线程中能很好使用
  • 避免了复杂且容易出错的依赖性和生命周期问题
  • 可以灵活方便指定工作线程和优先级
  • 速度快,性能好,代码简单优雅
  • 库比较小,不占内存

机制

操作步骤

添加依赖

  • build.gradle
kotlin 复制代码
dependencies {
    implementation "org.greenrobot:eventbus:3.2.0"
}

定义事件对象

事件对象可以是任意类型,没有特殊要求,比如 String、int、自定义类等。

  • bean/MessageEvent.kt
kotlin 复制代码
class MessageEvent(
    val name: String = ""
)

准备订阅者

订阅者时实现订阅方法,需要使用@Subscirbe 来注释订阅,具体要求下:

  • 例子
kotlin 复制代码
/**
  * 事件接收
  */
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(messageEvent: MessageEvent) {
    binding.acceptText.text = messageEvent.name
}

@Subscribe注解参数中,threadMode参数决定了使用的线程模型,目前一共有五种:

kotlin 复制代码
/**
  * 粘性事件接收
  */
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onStickyEvent(messageEvent: MessageEvent) {
    binding.acceptText.text = messageEvent.name
    EventBus.getDefault().removeStickyEvent(message)
}

注册和注销

在发布事件之前需要先注册订阅者,在生命周期结束的时候,需要注销订阅者

(images.sunofbeaches.com//images/202...)

kotlin 复制代码
/**
  * 生命周期开始的时候注册
  */
override fun onStart() {
    super.onStart()
    EventBus.getDefault().register(this)
}

/**
  * 生命周期结束的时候取消注册
  */
override fun onStop() {
    super.onStop()
    EventBus.getDefault().unregister(this)
}

发布事件

注册订阅者之后,就可以发布事件了,目前有两种事件:

  • 调用EventBus.getDefault().post(Object)发布普通事件
  • 调用EventBus.getDefault().postSticky(Object)发布粘性事件

(images.sunofbeaches.com//images/202...)

kotlin 复制代码
/**
 * 发布事件
 */
fun postEvent() {
    val message = MessageEvent()
    message.name = "show event"
    EventBus.getDefault().post(message)
    finish()
}

/**
 * 发布粘性事件
 */
fun postStickyEvent() {
    val message = MessageEvent()
    message.name = "show test"
    EventBus.getDefault().postSticky(message)
    finish()
}

混淆

@Subscribe 订阅方法是通过反射调用的,在编译时没有直接调用,如果不增加反混淆规则的话,在运行时会出现找不到方法名的情况。因此,EventBus 需要配置以下混淆规则:

kotlin 复制代码
-keepattributes *Annotation*
// keep住所有被Subscribe注解标注的方法
-keepclassmembers class * {
   @org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }

如果使用了 AsyncExecutor,还需要配置混淆规则:

kotlin 复制代码
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
    <init>(java.lang.Throwable);
}

更多内容: 《Android | 代码混淆到底做了什么?》


总结

  • EventBus 是一套 Android / Java 事件订阅 / 发布框架,用于在组件 / 线程间通信的场景中将数据或事件传递给订阅者,EventBus 的特点是可以实现事件订阅者与发布者解耦,以及透明地线程切换;

  • @Subscribe 订阅方法是通过反射调用的,在编译时没有直接调用,如果不增加反混淆规则的话,在运行时会出现找不到方法名的情况。

相关推荐
方白羽11 小时前
Android Gradle 缓存与文件目录深度解析
android·gradle·android studio
曲幽15 小时前
Termux里的二进制和脚本,到底怎么运行才不踩坑?Termux-service 保活妙招!
android·termux·nohup·services·wake-lock
plainGeekDev16 小时前
单例模式 → object 声明
android·java·kotlin
程序员陆业聪16 小时前
读者点单·03|Compose 与传统 View 混用的 12 个真实坑
android
程序员陆业聪16 小时前
读者点单·02|Android 启动优化实战:Trace 抓取→Application 编排→冷启动全流程拆解
android
Coffeeee17 小时前
帮你快速理解AI Agent之我想招个Android实习生
android·人工智能·agent
恋猫de小郭18 小时前
苹果 AirPods 协议,Android 也可以使用完整版 AirPods 能力
android·前端·flutter
黄林晴18 小时前
告别无效重建:Gradle 9.6.0 解决 CI 构建缓存失效痛点告别无效重建:Gradle 9.6.0 解决 CI 建筑缓存失效痛点
android·gradle
张风捷特烈19 小时前
Flutter 类库大揭秘#01 | path_provider架构与设计
android·flutter
_阿南_1 天前
Android文件读写和分享总结
android