【问题标题】:How to emit data from an asycnhronous callback using Kotlin Flow?如何使用 Kotlin Flow 从异步回调中发出数据?
【发布时间】:2021-02-13 19:42:19
【问题描述】:
我开始学习 Kotlin Flow 和 Coroutines,但我不知道如何使下面的代码工作。我做错了什么?
interface MessagesListener {
fun onNewMessageReceived(message: String)
}
fun messages(): Flow<String> = flow {
val messagesListener = object : MessagesListener {
override fun onNewMessageReceived(message: String) {
// The line below generates the error 'Suspension functions can be called only within coroutine body'
emit(message)
}
}
val messagesPublisher = MessagesPublisher(messagesListener)
messagesPublisher.connect()
}
【问题讨论】:
标签:
android
kotlin
kotlin-coroutines
【解决方案1】:
我相信你应该可以使用callbackFlow ....类似的东西:
fun messages(): Flow<String> = callbackFlow {
val messagesListener = object : MessagesListener {
override fun onNewMessageReceived(message: String) {
trySend(message)
}
}
val messagesPublisher = MessagesPublisher(messagesListener)
messagesPublisher.connect()
}
【解决方案2】:
您试图实现的目标是不可能的,因为 emit 是一个 suspend 函数。
但是,您可以使用专为此类情况设计的 callbackFlow 将 Listeners/Callbacks 转换为 Coroutine 的 Flows。
fun messages() = callbackFlow<String> {
val messagesListener = object : MessagesListener {
override fun onNewMessageReceived(message: String) {
offer(message)
}
}
val messagesPublisher = MessagesPublisher(messagesListener)
messagesPublisher.connect()
}