在 kotlin 协程中取消后如何重新启动作业?

How to restart job after cancel in kotlin coroutines?

如何在 kotlin coroutines

中取消后重新启动 job

我有 2 个按钮,一个用于启动协程,另一个用于取消作业。 但是在我取消作业后,协程不会再次启动。

class TestFragment : Fragment(), CoroutineScope {

    private lateinit var job: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = SettingFragmentBinding.inflate(inflater, container, false)

        job = Job()

        button1.setOnClickListener {
            launch {
                val currentTime = LocalDateTime.now()
                println(currentTime)
            }
        }

        button2.setOnClickListener {
            job.cancel()
        }

        return binding.root
    }

}

您不恰当地使用链接到片段生命周期的顶级作业作为按需取消协程的方式。

替换此样板文件:

class TestFragment : Fragment(), CoroutineScope {

    private lateinit var job: Job
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job

有了这个:

class TestFragment : Fragment(), CoroutineScope by MainScope {
    override fun onDestroy() {
        cancel()
    }

这将自动解决您引入的问题之一:它使用 SupervisorJob 而不是普通的 Job

接下来,您需要访问您在 onClick 中启动的作业:

    private var button1Job: Job?

    ...

    button1.setOnClickListener {
        button1Job = launch {
           ...
           button1Job = null
        }

您现在可以在 button2 侦听器中取消此作业:

    button1Job?.cancel()

除了上述答案,你还应该使用

 button1Job.cancelChildren()

这保留了作业的完整性并确保它可以在取消后重新启动,这与影响作业状态的取消不同