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

相关推荐
androidwork2 小时前
嵌套滚动交互处理总结
android·java·kotlin
fatiaozhang95273 小时前
中兴B860AV1.1强力降级固件包
android·adb·电视盒子·av1·机顶盒rom·魔百盒刷机
橙子199110164 小时前
Kotlin 中的 Object
android·开发语言·kotlin
AD钙奶-lalala8 小时前
android:foregroundServiceType详解
android
大胃粥11 小时前
Android V app 冷启动(13) 焦点窗口更新
android
fatiaozhang952715 小时前
中兴B860AV1.1_晨星MSO9280芯片_4G和8G闪存_TTL-BIN包刷机固件包
android·linux·adb·电视盒子·av1·魔百盒刷机
fatiaozhang952717 小时前
中兴B860AV1.1_MSO9280_降级后开ADB-免刷机破解教程(非刷机)
android·adb·电视盒子·av1·魔百盒刷机·移动魔百盒·魔百盒固件
二流小码农17 小时前
鸿蒙开发:绘制服务卡片
android·ios·harmonyos
微信公众号:AI创造财富17 小时前
adb 查看android 设备的硬盘及存储空间
android·adb