You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中SharedFlow无法收集值问题排查求助

解决SharedFlow无控制台输出的问题

你的代码出现无输出的核心原因有两个:

  1. 主线程提前终止:main函数执行完毕后会直接结束JVM进程,GlobalScope启动的后台协程会被强制终止,根本没机会完成事件发送或收集逻辑。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:46:18