【问题标题】:Job delay is not started again after canceling取消后作业延迟未再次启动
【发布时间】:2021-12-30 20:53:15
【问题描述】:

所以当我按下一个按钮时,我需要等待 3 秒钟才能执行另一种方法,我用以下方法解决了这个问题

val job = CoroutineScope(Dispatchers.Main).launch(Dispatchers.Default, CoroutineStart.DEFAULT) {
    delay(THREE_SECONDS)
    if (this.isActive)
        product?.let { listener?.removeProduct(it) }
}



override fun onRemoveProduct(product: Product) {
        job.start()
    }

现在,如果我在开始工作后立即按下取消按钮,我会停止工作,并且工作正常

 override fun onClick(v: View?) {
        when(v?.id) {
            R.id.dismissBtn -> {
                job.cancel()
            }
        }
    }

问题是当我再次执行 onRemoveProduct 执行 job.start() 时它不会再次启动,似乎 job.isActive 永远不会屈服于 true,为什么会发生这种情况?

【问题讨论】:

    标签: android kotlin kotlin-coroutines jobs


    【解决方案1】:

    Job 一旦取消就无法再次启动。你需要以不同的方式做到这一点。一种方法是在每次调用 onRemoveProduct 时创建一个新作业。

    private var job: Job? = null
    
    fun onRemoveProduct(product: Product) {
        job = scope.launch {
            delay(THREE_SECONDS)
            listener?.removeProduct(product) // Assuming the two products are same. If they aren't you can modify this statement accordingly.
        }
    }
    
    fun cancelRemoval() { // You can call this function from the click listener
        job?.cancel()
    }
    

    另外,在你的这行代码CoroutineScope(Dispatchers.Main).launch(Dispatchers.Default, CoroutineStart.DEFAULT)

    • 您不应该/不需要自己创建新的协程作用域。您可以/应该使用已经提供的viewModelScopelifecycleScope。它们是更好的选择,因为它们具有生命周期意识并在正确的时间被取消。
    • Dispatchers.Main 没用,因为无论如何它都会被 Dispatchers.Default 取代。 Dispatchers.Default 这里也不需要,因为你没有在这里做任何繁重的计算(或调用一些阻塞代码)。
    • CoroutineStart.DEFAULT 是默认参数,因此您可以跳过该参数。

    你也不需要检查if (this.isActive),因为

    如果当前协程的 [Job] 在 delay 等待时被取消或完成,它会立即以 [CancellationException] 恢复。

    【讨论】:

    • Dispatchers.Default 也无用,因为从不调用阻塞代码。
    • 啊,你是对的。编辑了答案。
    • 我无法使用 viewmodelscope 或生命周期范围,因为它在作业类上运行,而不是在其中任何一个中运行
    猜你喜欢
    • 2010-12-15
    • 1970-01-01
    • 2012-03-21
    • 2011-03-24
    • 2013-06-10
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    相关资源
    最近更新 更多