如何使用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 订阅方法是通过反射调用的,在编译时没有直接调用,如果不增加反混淆规则的话,在运行时会出现找不到方法名的情况。

相关推荐
日光明媚20 小时前
一步生成视频!One-Forcing:DMD + 零成本 GAN,训练 200 步超越多步 SOTA
android·开发语言·kotlin
帅次20 小时前
Android 17 开发者实战:核心更新与应用场景落地指南
android·java·ios·android studio·iphone·android jetpack·webview
大鹏说大话21 小时前
SQL 排序与分组实战:解决“分组后取最新数据“
android·java·数据库
搜狐技术产品小编20231 天前
破局与重构:纯端侧 Android 自动化引擎的尝试与未来推演
android·运维·重构·自动化
码云骑士1 天前
Android SystemServer启动过程
android·systemserver
weiggle1 天前
第三篇:可组合函数(Composable)——Compose 的基石
android·前端
独隅1 天前
Android Studio 接入多种不同 AI 大模型进行开发的全面详细指南(Android Studio+AI)
android·人工智能·android studio
夜微凉41 天前
三、MySQL
android·数据库·mysql
我命由我123451 天前
Android 开发问题:项目同时引入了两个包含相同类文件的库(AndroidX 库、旧版本支持库),导致了重复类错误
android·java·java-ee·android studio·android-studio·androidx·android runtime
anthonyzhu1 天前
安卓Android studio panda run无法应用更新的问题
android·ide·android studio