Kotlin Flow: Suspension functions can be called only within coroutine body
2022/04/16
Flowのemitでエラー
例えば、Zipにアーカイブしている最中にprogressをemitできない問題。
fun startPacking() = flow {
...
ZipUtil.pack(baseDir, exportPath) { name ->
...
val progress: Float = packingFiles / totalFiles
emit(progress)// Suspension functions can be called only within coroutine body
name
}
}.flowOn(Dispatchers.IO)
CallbackFlow
こうゆう場合はcallbackFlowに替えると解決します。emit => trySend or send、最後にawaitClose()を呼びます。チェンジリスナーを使っていた場合は、awaitCloseで解放させて下さい。
実験的なので仕様が変わるかもしれません。
@OptIn(ExperimentalCoroutinesApi::class)
fun startPacking() = callbackFlow {
...
ZipUtil.pack(baseDir, exportPath) { name ->
...
val progress: Float = packingFiles / totalFiles
trySend(progress)
name
}
awaitClose()
}.flowOn(Dispatchers.IO)