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

Kotlin Flow代码块未执行 调用控制权返回ViewModel问题排查

Kotlin协程Flow代码块未执行问题排查

核心成因

  • 最直接原因:Flow是冷流,你没有调用末端操作符触发流执行。onEach属于中间操作符,仅做数据转换/侧处理逻辑,不会启动flow{}代码块的执行,只有调用collect、collectLatest、first()这类末端操作符时,Flow才会真正开始运行生产数据的逻辑。你当前ViewModel层的代码只调用了onEach,没有加末端收集操作,所以Repository层的flow{}代码块根本不会被触发,调用后控制权直接返回。
  • 隐藏问题:你当前Repository层的Flow实现本身不符合异步回调场景的使用规范,就算加上collect触发流执行,flow{}代码块在调用完ftpClient.connect后会立刻执行完毕退出,无法等待异步回调返回,onSuccess/onFail里的结果根本没法发射到流中。

修正方案

1. 补全ViewModel层的Flow末端收集逻辑

在onEach链式调用后加上collect()触发流执行,修正后代码如下:

fun getFilesFromServer() {
    viewModelScope.launch(Dispatchers.IO) {
        ftpRepository.getFilesFromServer()
            .onEach { state ->
                when (state) {
                    is Resource.Loading -> {
                        liveData.postValue(Resource.Loading())
                    }
                    is Resource.Success -> liveData.postValue(state)
                    is Resource.Error -> liveData.postValue(state)
                }
            }
            .collect() // 必须添加末端操作符,才会触发Flow执行
    }
}

2. 替换Repository层的flow实现为callbackFlow

针对FTP连接这种异步回调场景,使用callbackFlow来实现回调到Flow的转换,保证回调结果可以正常发射、流生命周期和协程绑定,修正后代码如下:

// 注意这里不需要加suspend修饰符,callbackFlow返回的冷流本身在协程上下文执行
override fun getFilesFromServer(): Flow<Resource<Response>> = callbackFlow {
    // 首先发射加载状态
    trySend(Resource.Loading())

    ftpClient.connect(
        Constants.SERVER_IP, Constants.PORT,
        Constants.USER_NAME,
        Constants.PASSWORD,
        object : OnEZFtpCallBack<Void?> {
            override fun onSuccess(response: Void?) {
                val fileList = requestFtpFileList()
                trySend(Resource.Success(fileList))
                close() // 结果发射完成后关闭流
            }

            override fun onFail(code: Int, msg: String) {
                trySend(Resource.Error(code, msg))
                close() // 请求失败时关闭流
            }
        }
    )

    // 流被取消时主动释放FTP连接,避免资源泄漏
    awaitClose {
        // 替换成你项目中实际的FTP断开连接方法
        ftpClient.disconnect()
    }
}

内容的提问来源于stack exchange,提问作者shehzy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:54:25