如何使用Kotlin Flow从异步回调发出数据?

时间:2020-10-31 16:03:16

标签: android kotlin kotlin-coroutines kotlin-coroutines-flow

我开始学习Kotlin Flow和协程,但是我不知道如何使下面的代码有效。我在做什么错了?

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()
}

2 个答案:

答案 0 :(得分:5)

我相信您应该可以使用callbackFlow...。类似

fun messages(): Flow<String> = callbackFlow {

    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {

            // The line below generates the error 'Suspension functions can be called only within coroutine body'

            offer(message)
        }
    }

    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}

答案 1 :(得分:3)

由于emitsuspend函数,因此您无法实现的目标。

但是,您可以使用专为此类情况设计的callbackFlow将侦听器/回调转换为协程流。

fun messages() = callbackFlow<String> {
    val messagesListener = object : MessagesListener {
        override fun onNewMessageReceived(message: String) {
            offer(message)
        }
    }
    val messagesPublisher = MessagesPublisher(messagesListener)
    messagesPublisher.connect()
}