在 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()
这保留了作业的完整性并确保它可以在取消后重新启动,这与影响作业状态的取消不同
如何在 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()
这保留了作业的完整性并确保它可以在取消后重新启动,这与影响作业状态的取消不同