I am using StateFlow in my app and in my Fragment I use this to -
private var job: Job? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
job = lifecycleScope.launchWhenResumed {
viewModel.getData().collect {
// ...
}
}
}
override fun onPause() {
job?.cancel()
super.onPause()
}
As you see I cancel the job in onPause. How could I use a generalized function so that I can avoid doing the job?.cancel in every fragment.
I prefer not to use a BaseFragment
a new way:
// Start a coroutine in the lifecycle scope
lifecycleScope.launch {
// repeatOnLifecycle launches the block in a new coroutine every time the
// lifecycle is in the STARTED state (or above) and cancels it when it's STOPPED.
repeatOnLifecycle(Lifecycle.State.STARTED) {
}
}
A simple solution would be to utilize the fragments lifecycle to automatically cancel the job when it is paused.
fun CoroutineScope.launchUntilPaused(lifecycleOwner: LifecycleOwner, block: suspend CoroutineScope.() -> Unit){
val job = launch(block = block)
lifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver {
override fun onPause(owner: LifecycleOwner) {
job.cancel()
lifecycleOwner.lifecycle.removeObserver(this)
}
})
}
//Usage
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
lifecycleScope.launchUntilPaused(this){
someFlow.collect{
...
}
}
}
}
If you have many of these jobs per fragment, I would advice to use a custom CoroutineScope instead, to avoid having many lifecycle observers active.
class CancelOnPauseScope(lifecycleOwner: LifecycleOwner): CoroutineScope by MainScope(){
init{
lifecycleOwner.lifecycle.addObserver(object : DefaultLifecycleObserver{
override fun onPause(owner: LifecycleOwner) {
cancel()
lifecycleOwner.lifecycle.removeObserver(this)
}
})
}
}
class MyFragment: Fragment() {
private val scope = CancelOnPauseScope(this)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
scope.launch{
someFlow.collect{
...
}
}
}
}
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