Sticky EventBus仅进入Activity时才触发问题求助
我有两个Activity,想在不启动Activity B的前提下,从Activity A向Activity B发送事件。尝试用Sticky EventBus实现,但发现只有进入Activity B后事件才会被触发,不清楚问题出在哪,相关代码如下:
Activity B 代码
override fun onStart() { super.onStart() registerEventBus() } override fun onDestroy() { super.onDestroy() unregisterEventBus() } @Subscribe(sticky = true, threadMode = ThreadMode.MAIN) fun onStickyEventBus(case: EventBusType?) { when (case) { EventBusType.ONE_FOR_PAYMENT_COMPLETED ->{ // do something removeEvent(case) } else -> {} } }
Activity A 代码
... postEvent(EventBusType.ONE_FOR_PAYMENT_COMPLETED,sticky = true)
扩展函数代码
fun postEvent(event: Any?, sticky: Boolean = false) { if (sticky) EventBus.getDefault().postSticky(event) else EventBus.getDefault().post(event) } fun removeEvent(event: Any?) { EventBus.getDefault().removeStickyEvent(event) } fun Activity.registerEventBus() { if (!EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().register(this) } } fun Activity.unregisterEventBus() { if (EventBus.getDefault().isRegistered(this)) { EventBus.getDefault().unregister(this) } }
问题根源
Sticky EventBus的核心逻辑是:粘性事件会被EventBus缓存,当有订阅者完成注册时,才会自动将缓存的粘性事件分发给匹配的订阅方法。
你的代码中,Activity B的EventBus注册逻辑在onStart()方法里——只有当Activity B被启动并执行到onStart()时,才会完成订阅者注册,此时EventBus才会把之前缓存的粘性事件推送给它的订阅方法。如果Activity B从未启动,它的实例都不存在,根本不会执行注册逻辑,自然无法接收事件。
可行解决方案
如果需要在Activity B未启动的场景下,让后续启动的B能响应之前的事件,或者要在B不启动时执行对应逻辑,需要换思路:
方案1:全局状态存储 + 启动时校验
这是最直接的替代方案,通过全局存储记录事件状态,待Activity B启动时再执行逻辑:
- 在Activity A中,将事件状态(比如支付完成标记)存入全局存储(单例类、SharedPreferences、数据库都可以)。
- 当Activity B启动后,在
onCreate()或onStart()中检查全局存储的状态,若存在对应标记则执行逻辑,随后清除标记。
示例代码(用单例类存储):
// 全局状态管理单例 object AppEventTracker { var paymentCompletedEvent = false } // Activity A中替换原postEvent逻辑 AppEventTracker.paymentCompletedEvent = true // Activity B的onStart()中添加校验逻辑 override fun onStart() { super.onStart() if (AppEventTracker.paymentCompletedEvent) { // 执行原订阅方法中的业务逻辑 AppEventTracker.paymentCompletedEvent = false // 清除标记,避免重复执行 } registerEventBus() }
方案2:使用后台Service处理逻辑
如果需求是Activity B不启动也要执行事件对应的逻辑,那么Activity作为UI组件并不适合承担这个任务——Activity只有在可见/前台时才有实例。此时应该将逻辑移至Service中,让Service作为订阅者注册到EventBus,即使在后台也能接收并处理粘性事件。
补充说明
Sticky EventBus的设计场景是订阅者后续会被启动,需要接收之前发送的事件,而非让未初始化的组件直接响应事件。如果你的核心需求是触发后台逻辑,优先考虑Service;如果只是需要后续启动的Activity能感知之前的事件,方案1足够满足需求。
内容的提问来源于stack exchange,提问作者Flutra Demaj

