A cold flow backed by a channel
or using operators with buffers such as buffer
, conflate
, flowOn
, or shareIn
is not safe to collect with some of the existing APIs such as CoroutineScope.launch
, Flow<T>.launchIn
, or LifecycleCoroutineScope.launchWhenX
, unless you manually cancel the Job
that started the coroutine when the activity goes to the background. These APIs will keep the underlying flow producer active while emitting items into the buffer in the background, and thus wasting resources.
To solve this issue with these APIs, you’d need to manually cancel collection when the view goes to the background. but it sounds to be a boilerplate code.
That's why Google recommended repeatOnLifecycle(Lifecycle.State.XXX)
to make it simple and safe.
repeatOnLifecycle
is a suspend function that takes a Lifecycle.State
as a parameter which is used to automatically create and launch a new coroutine with the block passed to it when the lifecycle reaches that state
, and cancel the ongoing coroutine that’s executing the block when the lifecycle falls below the state.
Learn more from here
launchWhenStarted suspends the execution of the coroutine, and repeatOnLifecycle cancels and restarts a new coroutine
This is the difference. If you have a running coroutine launched withlauchWhen...
and the lifecycle goes below that level, the coroutine will be suspended (but will still be alive, so depending what else it does, you may be wasting resources in things you don't need). The newerrepeatOn...
is "smarter" as it can cancel the coroutine and start a new one when needed. The easiest way to see this, is to try them yourself. – Lottery