无法在 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
块)。上面的解决方案应该可以解决问题。
我正在尝试实现 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
块)。上面的解决方案应该可以解决问题。