Kotlin中SharedFlow无法收集值问题排查求助
你的代码出现无输出的核心原因有两个:
- 主线程提前终止:
main函数执行完毕后会直接结束JVM进程,GlobalScope启动的后台协程会被强制终止,根本没机会完成事件发送或收集逻辑。 - SharedFlow默认无重播机制:
MutableSharedFlow默认replay = 0,新启动的收集者无法接收之前发送的事件。你的代码里第一个协程先发送了0-9的数值,之后第二个协程才开始收集,这些早期事件直接丢失了。
修复方案
用runBlocking阻塞主线程保证协程执行时间,同时调整协程启动顺序(或设置重播参数)确保事件能被收集:
import kotlinx.coroutines.delay import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlin.time.Duration.Companion.seconds fun main() = runBlocking { val eventBus = EventBus() // 先启动收集协程,确保事件发送时已有订阅者 launch { eventBus.value.collect { println("value received: $it") } } // 再启动发送事件的协程 launch { repeat(10) { eventBus.increment(it) } delay(10.seconds) (10..20).forEach { eventBus.increment(it) } } } class EventBus { // 若需要让后续启动的收集者也能接收历史事件,可设置replay参数(比如replay=10保留最近10个事件) private val _value = MutableSharedFlow<Int>() val value: SharedFlow<Int> = _value.asSharedFlow() suspend fun increment(number: Int) { _value.emit(number) } }
关键修改说明
runBlocking:让主线程等待内部所有协程执行完毕,避免进程提前退出。- 协程启动顺序:先启动收集逻辑再发送事件,确保所有发送的事件都能被当前订阅者捕获。如果需要支持后续订阅者接收历史事件,可在
MutableSharedFlow初始化时指定replay参数值。
内容的提问来源于stack exchange,提问作者Compose Learner
相关产品推荐
相关产品推荐

