Sergey
Sergey

Reputation: 160

Cancel file upload (retrofit) started from coroutine kotlin android

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?

Upvotes: 4

Views: 2902

Answers (1)

Adib Faramarzi
Adib Faramarzi

Reputation: 4062

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.")
}

Upvotes: 3

Related Questions