无法在 Android 上使用 flow 或 channelFlow 发出数据

Cannot emit data using flow or channelFlow on Android

我正在尝试实现 One Tap,因此我创建了一个如下所示的函数:

override suspend fun oneTapSgnInWithGoogle() = flow {
    try {
        emit(Result.Loading)
        val result = oneTapClient.beginSignIn(signInRequest).await()
        emit(Result.Success(result))
    } catch (e: Exception) {
        Log.d(TAG, "oneTapSgnInWithGoogle: ${e.message}")
        emit(Result.Error(e.message!!))
    }
}

如果我使用 flow 并尝试 emit 结果,我的应用程序崩溃并显示以下消息:

Flow exception transparency is violated: StandaloneCoroutine has completed normally; but then emission attempt of value 'Error(message=StandaloneCoroutine has completed normally)' has been detected.

但是,如果将代码更改为:

override suspend fun oneTapSgnInWithGoogle() = channelFlow {
    try {
        send(Result.Loading)
        val result = oneTapClient.beginSignIn(signInRequest).await()
        send(Result.Success(result))
    } catch (e: Exception) {
        Log.d(TAG, "oneTapSgnInWithGoogle: ${e.message}")
        send(Result.Error(e.message!!))
    }
}

然后我使用 channelFlow 并尝试 send 结果,应用程序没有崩溃,但我仍然收到错误消息:

StandaloneCoroutine has completed normally

如何才能正确发出结果并消除此错误消息?

P.S。在我的 ViewModel class 中,我使用:

fun oneTapSgnInWithGoogle() = liveData(Dispatchers.IO) {
    viewModelScope.launch {
        repo.oneTapSgnInWithGoogle().collect { result ->
            emit(result)
        }
    }
}

这不是在 liveData 块中启动协程的好习惯。 liveData 块是一个 suspend lambda,您可以直接在其中收集值而无需启动协程:

fun oneTapSgnInWithGoogle() = liveData(Dispatchers.IO) {
    repo.oneTapSgnInWithGoogle().collect { result ->
        emit(result)
    }
}

在您的情况下,当您尝试向 LiveData 发出值时,liveData 块已经完成执行(以及相应的协程,其中执行了 liveData 块)。上面的解决方案应该可以解决问题。