写个demo测试下,sharedFlow实现事件监听。
添加依赖:
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
定义事件:
Kotlin
package com.example.testnavigation
/**
* 定义事件
*/
// 普通消息事件
data class MessageEvent(val content: String)
// 登录状态事件
data class LoginEvent(val isLogin: Boolean)
SharedFlow事件总线:
Kotlin
package com.example.testnavigation
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
/**
* SharedFlow 事件总线(单例,全局唯一)
*/
object EventBus {
// 1. 定义可变的 SharedFlow(内部使用,用于发送事件)
// replay = 0:不缓存旧事件(非粘性)
// extraBufferCapacity = 10:缓冲队列大小
private val _events = MutableSharedFlow<Any>(replay = 0, extraBufferCapacity = 10)
// 2. 对外暴露不可变的 SharedFlow(用于订阅事件)
val events: SharedFlow<Any> = _events
// 3. 全局协程作用域(发送事件用)
private val scope = CoroutineScope(Dispatchers.IO)
/**
* 发送事件
*/
fun post(event: Any) {
scope.launch {
_events.emit(event) // 发射事件
}
}
}
MainActivity订阅事件:
Kotlin
package com.example.testnavigation
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.FragmentActivity
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
class MainActivity : FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main1)
findViewById<Button>(R.id.btn_goto_second).setOnClickListener {
startActivity(Intent(this@MainActivity, MainActivity2::class.java))
}
// 订阅 MessageEvent 事件
EventBus.events
.filter { it is MessageEvent } // 只接收 MessageEvent 类型
.onEach { event ->
// 收到事件,处理逻辑
val msg = event as MessageEvent
println("收到消息:${msg.content}")
val tv_msg = findViewById<TextView>(R.id.tv_msg)
tv_msg.text = msg.content
}
.launchIn(CoroutineScope(Dispatchers.Main)) // 生命周期绑定
// 订阅 LoginEvent 事件
EventBus.events
.filter { it is LoginEvent }
.onEach { event ->
val login = event as LoginEvent
println("登录状态:${login.isLogin}")
}
.launchIn(CoroutineScope(Dispatchers.Main))
}
}
第二个activity发送事件:
Kotlin
package com.example.testnavigation
import android.os.Bundle
import android.widget.Button
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class MainActivity2: FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_2)
findViewById<Button>(R.id.btn_send_event).setOnClickListener {
EventBus.post(MessageEvent("竹外桃花三两枝,春江水暖鸭先知"))
lifecycleScope.launch {
delay(1000)
finish()
}
}
}
}
运行:

点击跳转到第二个activity:

点击发送数据:

ok. 实现了和以前eventBus一样的效果,还简单,不用写注解。