Home > Back-end >  How to relaunch a coroutine on each Fragment.onResume call?
How to relaunch a coroutine on each Fragment.onResume call?

Time:11-04

I have some coroutine that should be relaunched on each onResume() call of Fragment.

I have tried the following approach:

val renderer = ...
val outerFlow = ...
val lifecycleCoroutineScope = myFragment.viewLifecycleOwner.lifecycleScope

lifecycleCoroutineScope.launchWhenResumed {
   outerFlow.onEach(renderer::render).launchIn(this)
}

But it only works until the Fragment's view destroyed first time. I mean the second and the following onResume() calls became ignored.

So please help me to find out: how to properly launch my coroutine on each onResume() call?

CodePudding user response:

I believe it doesn't work because of calling launchIn(this). Please try to call another terminal operator, like collect:

lifecycleCoroutineScope.launchWhenResumed {
   outerFlow.collect(renderer::render)
}

In the docs they say that:

This API is not recommended to use as it can lead to wasted resources in some cases. Please, use the Lifecycle.repeatOnLifecycle API instead. This API will be removed in a future release.

With the Lifecycle.repeatOnLifecycle it will look something like the following:

lifecycleScope.launch {
    lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
        outerFlow.collect(renderer::render)
    }
}

CodePudding user response:

I've solved the issue.

The problem was not in coroutines. It was in LifecycleOwner. After Lifecycle gets Lifecycle.State.DESTROYED state it also destroys and doesn't work anymore.

I was bound to Fragment view's lifecycle. And after we leave the current Fragment, its view's lifecycle gets destroyed.

So replacing fragment.viewLifecycleOwner.lifecycleScope to fragment.lifecycleScope helped me.

  • Related