Выглядит примерно так:
interface UserCallbacks {
fun onSomeMessage(msg: SomeType)
fun onOtherMessage(msg: OtherType)
}
class LibraryApi(callbacks: UserCallbacks) {
fun parse(msg: Array<Byte>)
}
Разумеется, никаким suspend-ом там не пахнет, ибо джава. Поэтому так просто это в корутины не протащить. Код типа такого:
suspend fun parse(msg: Array<Byte>): MessageBaseType {
return suspendCoroutine { cont ->
val callbacks = object: UserCallbacks {
override fun onSomeMessage(msg: SomeMessage) { cont.complete(msg) }
}
new LibraryApi(callbacks).parse(msg)
}
}
так просто не скомпилится, компилятору не нравится вызов suspend-функции complete изнутри не-suspend API
Вопрос: есть ли способ пообещать компилятору "мамой клянусь, эту не-suspend функцию можно вызвать внутри suspend, там ни переключения потоков, ни IO, ни сложных вычислений"?
https://stackoverflow.com/questions/48552925/existing-3-function-callback-to-kotlin-coroutines
Надо сделать на однократный колбэк или на регулярный?
В идеале регулярный, и это отдельная проблема (постоянно в объекте колбэков поле менять?)
Ищите callbackFlow и там прямо в доке решение
А в чём вопрос? Кстати, API напрочь поехавшее, даже без учёта джавы)
Действительно, через channel можно вывернуться, спасибо
не channel, а конкретно callbackFlow, он специально для этого сделан
Дописал в исходное сообщение. API перректалное, согласен, но с этим приходится смириться. У этих товарищей на гитхаб выложены не исходники кода, а страничка для скачивания zip-ника с исходникми 😃
Хм, заинтриговали, пойду пересмотрю API Channel. Решение, конечно, найдено, но чисто из любопытства, на исходный вопрос: есть ли способ пообещать компилятору "мамой клянусь, эту не-suspend функцию можно вызвать внутри suspend, там ни переключения потоков, ни IO, ни сложных вычислений"? - ответ отрицательный?
Вижу. Но не очень понимаю проблему. У Continuation есть метод resume, в который можно передать результат. А у вас какой-то complete 🤔
https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/callback-flow.html Вот прям разобрано
complete читать как resume :) Писал по памяти. Проблема в том, что я вызываю suspend из оверрайда джавовского API, которое естественно не suspend, и компилятор такое не пропустит
Так resume не suspend
Обсуждают сегодня