How to observe Ktor download progress by a Flow
I want to observe the download progress by a Flow, so I wrote a function like this:
suspend fun downloadFile(file: File, url: String): Flow<Int>{
val client = HttpClient(Android)
return flow{
val httpResponse: HttpResponse = client.get(url) {
onDownload { bytesSentTotal, contentLength ->
val progress = (bytesSentTotal * 100f / contentLength).roundToInt()
emit(progress)
}
}
val responseBody: ByteArray = httpResponse.receive()
file.writeBytes(responseBody)
}
}
but the onDownload
will be called only once, and the file will not be downloaded. If I remove the emit(progress)
it will work.
io.ktor:ktor-client-android:1.6.7
Use callbackFlow
instead of flow
. A regular flow can't launch background code, and can only emit values from code inside the flow itself. Meanwhile, a callback flow can launch other work in the background, and then receive callbacks from it.