【问题标题】:Cancel file upload (retrofit) started from coroutine kotlin android取消文件上传(改造)从协程kotlin android开始
【发布时间】:2018-11-06 05:18:30
【问题描述】:

我正在尝试在我的项目中摆脱 RxJava2 并用 kotlin 协程替换它。我 90% 的 RxJava 代码不再存在,但我仍然无法替换一个网络请求。 用户可以在我的应用程序中将照片发送到后端(使用改造的多部分表单数据请求)。如果尚未加载,用户也可以取消照片上传。使用 RxJava,我可以保留上传请求的 Disposable 对象,如果尚未处理,如果用户单击取消上传按钮,我可以处理它。由于此操作,网络请求也被取消。所以我们可以节省一些用户流量和电池。 是否可以使用 kotlin 协程实现相同的逻辑?在官方文档中,协程取消是合作的,我们需要在循环中(或在文件部分发送之间)使用一些挂起函数来停止协程。 那么是 RxJava 是更好的选择还是我错过了什么?

【问题讨论】:

    标签: android networking kotlin kotlinx.coroutines


    【解决方案1】:

    如果您正在为网络调用使用改造,您可以从here 添加他们的协程调用适配器。

    您通过取消协程的工作来取消协程的运行部分。例如,如果您使用launch 来启动您的协程,它会返回一个可以取消的Job 对象。

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

    如果您不使用改造并使用另一个库,您可以在协程中检索 isActive 并取消来自您的库的请求。

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

    【讨论】:

    • 非常感谢!协程调用适配器正是我所需要的!但截至回答的第二部分(关于 isActive):我认为它不起作用。因为我没有任何循环或其他地方可以检查协程的 isActive 属性。 Retrofit 自己处理部分文件上传,我没有发现任何回调可以在上传过程中检查 isActive 。无论如何,再次感谢!
    • 没问题!你确定改造不会取消 OkHttp 请求调用吗?我在这里看不到 rx 和协程之间的区别,所以如果取消(rx 中的处置)有效,它也应该在协程中有效。
    • 是的,我检查了两次。取消协程不会取消 Retrofit 上传请求。 rx 和 coroutine 的区别在于改造调用适配器。我用来取消改造请求的一次性用品是由改造 rxjava 调用适配器创建的。这就是为什么这种一次性产品会对改造要求产生影响。你可以在这里看到它:linkpublic void dispose() 方法有 call.cancel 行。协程调用适配器做同样的事情。
    • 这很奇怪,因为它确实取消了下载端。也许您可以向适配器存储库提交问题。虽然他们的存储库已经声明这是一个实验性功能,所以如果他们在未来的版本中添加它,我不会感到惊讶。我也不认为创建自己的会那么难。您可以将代码从 Rx one 转换为“协程”样式。无论如何,祝你好运!
    • 在没有“Kotlin Coroutine Adapter”的情况下,还有其他方法可以取消改造请求吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    • 2021-10-13
    • 2023-01-22
    • 1970-01-01
    相关资源
    最近更新 更多