问题
I'm trying to get rid of RxJava2 in my project and replace it with kotlin coroutines. 90% of my RxJava code is no longer exists but I still can`t replace one network request. User can send photo to backend in my App (multipart form data request using retrofit). User also can cancel photo upload if it was not loaded yet. With RxJava I was able to keep Disposable object of upload request and if it is not disposed yet I could dispose it if user clicked cancel upload button. As result of this action network request was canceled too. So we could save some user traffic and battery. Is it possible to achieve same logic with kotlin coroutines? In official docs written that coroutines cancellation is cooperative and we need some suspending function in loop (or in between file parts send) in order to stop coroutine. So is this the case when RxJava is better choice or did I missed something?
回答1:
If you are using retrofit for your network calls, you can add their coroutines call adapter from here.
You cancel a coroutine's running part by cancelling it's job. For example if you are using launch
to launch your coroutine, it returns a Job
object which can be cancelled.
val job = launch {
repeat(1000) { i ->
println("I'm sleeping $i ...")
delay(500L)
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancel() // cancels the job
job.join() // waits for job's completion
println("main: Now I can quit.")
If you are not using retrofit and using another library, you can retrieve isActive
inside you coroutine and cancel the request from your library.
fun main(args: Array<String>) = runBlocking<Unit> {
val startTime = System.currentTimeMillis()
val job = launch {
var nextPrintTime = startTime
var i = 0
while (isActive) { // cancellable computation loop
// print a message twice a second
if (System.currentTimeMillis() >= nextPrintTime) {
println("I'm sleeping ${i++} ...")
nextPrintTime += 500L
}
}
}
delay(1300L) // delay a bit
println("main: I'm tired of waiting!")
job.cancelAndJoin() // cancels the job and waits for its completion
println("main: Now I can quit.")
}
来源:https://stackoverflow.com/questions/50552373/cancel-file-upload-retrofit-started-from-coroutine-kotlin-android