概述
EventBus 是适用于 Android 和 JAVA 的发布/订阅事件总线。主要功能是替代 Intent、Handler、BroadCast 在 Activity、Fragment、Service 线程之间传递消息。EventBus 能够简化应用组件间的通信,解耦 (有效分离) 事件的发送者和接收者,避免复杂和容易出错的依赖和生命周期问题,开销小,代码更优雅。但是需要注意的是 EventBus 不能用于进程间通信。
特性
Andorid 组件间通信,可能都是用 Handler 消息机制或者广播机制来实现通信,但是它们代码量大,组件上容易产生耦合 。为什么选择使用 EventBus 来做通信?
- 简化了组件间的通信
- 对事件通信双方进行解耦
- 在 Activity、Fragment 和后台线程中能很好使用
- 避免了复杂且容易出错的依赖性和生命周期问题
- 可以灵活方便指定工作线程和优先级
- 速度快,性能好,代码简单优雅
- 库比较小,不占内存
机制
操作步骤
添加依赖
- build.gradle
dependencies {
implementation "org.greenrobot:eventbus:3.2.0"
}
定义事件对象
事件对象可以是任意类型,没有特殊要求,比如 String、int、自定义类等。
- bean/MessageEvent.kt
class MessageEvent(
val name: String = ""
)
准备订阅者
订阅者时实现订阅方法,需要使用@Subscirbe 来注释订阅,具体要求下:
- 例子
/**
* 事件接收
*/
@Subscribe(threadMode = ThreadMode.MAIN)
fun onMessageEvent(messageEvent: MessageEvent) {
binding.acceptText.text = messageEvent.name
}
@Subscribe
注解参数中,threadMode
参数决定了使用的线程模型,目前一共有五种:
/**
* 粘性事件接收
*/
@Subscribe(threadMode = ThreadMode.MAIN, sticky = true)
fun onStickyEvent(messageEvent: MessageEvent) {
binding.acceptText.text = messageEvent.name
EventBus.getDefault().removeStickyEvent(message)
}
注册和注销
在发布事件之前需要先注册订阅者,在生命周期结束的时候,需要注销订阅者
(https://images.sunofbeaches.com//images/2024_07_10/1810843762209980418.png)
/**
* 生命周期开始的时候注册
*/
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)
发布粘性事件
(https://images.sunofbeaches.com//images/2024_07_10/1810853817403703297.png)
/**
* 发布事件
*/
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 需要配置以下混淆规则:
-keepattributes *Annotation*
// keep住所有被Subscribe注解标注的方法
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
如果使用了 AsyncExecutor,还需要配置混淆规则:
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent {
<init>(java.lang.Throwable);
}
更多内容: 《Android | 代码混淆到底做了什么?》
总结
-
EventBus 是一套 Android / Java 事件订阅 / 发布框架,用于在组件 / 线程间通信的场景中将数据或事件传递给订阅者,EventBus 的特点是可以实现事件订阅者与发布者解耦,以及透明地线程切换;
-
@Subscribe 订阅方法是通过反射调用的,在编译时没有直接调用,如果不增加反混淆规则的话,在运行时会出现找不到方法名的情况。