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

相关推荐
千里马学框架3 天前
一起学 Android 14:ShellTransition 屏幕旋转过程深度剖析
android·智能手机·性能优化·framework·性能·屏幕旋转·rotation
美狐美颜SDK开放平台3 天前
开发直播APP时如何接入视频美颜SDK?开发流程与注意事项
android·人工智能·计算机视觉·音视频·直播美颜sdk
AFinalStone3 天前
Android7 SystemUI源码解析(七)Keyguard锁屏模块深度解析
android·systemui
致远ccc3 天前
Google Play 上架前如何测试 App?多国家 Android 环境测试
android·app测试·googleplay·多国家应用测试
ttyyttemo3 天前
Kotlin 协程中的 Job 结构化并发与取消
android
sun0077003 天前
tbox 4g/5g切换,导致wan ip 改变,导致车机旧网络不可用。需要重启车机才行
android
其实防守也摸鱼3 天前
内网穿透与反向代理:原理、工具与实战指南
android·大数据·运维·安全·网络安全·自动化·渗透
AFinalStone3 天前
Android7 SystemUI 源码解析(四)NavigationBar 导航栏与 SystemBars
android·systemui
JMchen3 天前
属性动画原理与高级动画实现
android·kotlin·canvas
AFinalStone3 天前
Android7 SystemUI 源码解析(二)启动流程深度解析
android·systemui