How to restart job
after canceling in kotlin coroutines
I have 2 buttons, 1 to start coroutine and another to cancel the job. But after I cancel the job, coroutine not starts again.
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
}
}
In addition to the above answer, you should use
button1Job.cancelChildren()
This retains the integrity of the job and ensures it can be relaunched after cancellation unlike cancel which affects the state of the job
You're inappropriately using the top-level job linked to the lifecycle of the fragment as the means to cancel your coroutine on demand.
Replace this boilerplate:
class TestFragment : Fragment(), CoroutineScope {
private lateinit var job: Job
override val coroutineContext: CoroutineContext
get() = Dispatchers.Main + job
with this:
class TestFragment : Fragment(), CoroutineScope by MainScope {
override fun onDestroy() {
cancel()
}
This will automatically fix one of the problems you introduced: it uses a SupervisorJob
instead of a plain Job
.
Next, you need access to the job you launched in onClick
:
private var button1Job: Job?
...
button1.setOnClickListener {
button1Job = launch {
...
button1Job = null
}
You can now cancel this job in button2
listener:
button1Job?.cancel()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With