【问题标题】:How to cancel old coroutine when new one is called on same thread在同一线程上调用新协程时如何取消旧协程
【发布时间】:2019-12-01 15:18:47
【问题描述】:

目前我有这段代码。

如果用户停留在同一个 Fragment 上,我会从 API 获得 apiGetObject,我想用 resetTime - current 更新它(请注意,此值将始终为 3 分钟)。

此代码将needReload.value = true 延迟该时间。

GlobalScope.launch(Dispatchers.Main) {
    apiGetObject.value?.resetTime?.let {
        if (it - System.currentTimeMillis() > 0) {
            delay(it - System.currentTimeMillis())
        }
    }
    needReload.value = true
}

现在我在每个onResume 上检索对象以刷新数据(这是必须的)。所以如果在 3 分钟窗口内恢复 Fragment,就会启动另一个协程。

=> 这使得数据

我想要什么:

我想如果有一个新的协程启动,那么前一个被取消/销毁。有没有办法做到这一点(这个协程的其他解决方案是受欢迎的)

注意:我将 MVVM 与 LiveData 一起使用,我得到 apiGetObject 与 Retrofit 和 RX

【问题讨论】:

    标签: android multithreading kotlin coroutine kotlin-coroutines


    【解决方案1】:

    对于取消协程,您可以在启动协程时保留返回的“作业”对象的引用,当您想要停止该协程时,您可以调用“job.cancel()”

    在你的情况下,

    首先为job创建一个全局变量

    var job : Job? = null
    

    当你启动你的协程时

    job?.cancel()
    
    job = GlobalScope.launch(Dispatchers.Main) {
        apiGetObject.value?.resetTime?.let {
            if (it - System.currentTimeMillis() > 0) {
                delay(it - System.currentTimeMillis())
            }
        }
        needReload.value = true
    }
    

    所以在启动协程之前,如果前一个存在,我们将取消它。

    【讨论】:

    • 大声笑我想通了,也这样做了。无论如何,谢谢,我已经接受了你的回答
    猜你喜欢
    • 1970-01-01
    • 2017-05-15
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多