Google's library androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-alpha01 introduced three new APIs that fullfil the same use cases of flow-lifecycle-observer, and probably more: LifecycleOwner.addRepeatingJob, Lifecycle.repeatOnLifecycle, and Flow.flowWithLifecycle. You can check this Medium post and the official documentation for more information.
This library provides four Flow<T> extension functions for collecting flows in a lifecycle-aware manner.
Two of the extensions functions are for collecting Flow<T> while LifecycleOwner is in RESUMED state:
Flow<T>.collectWhileResumedIn(LifecycleOwner)Flow<T>.collectWhileResumed(LifecycleOwner, suspend (T) -> Unit)
The other two are for collecting Flow<T> while LifecycleOwner is in STARTED state:
Flow<T>.collectWhileStartedIn(LifecycleOwner)Flow<T>.collectWhileStarted(LifecycleOwner, suspend (T) -> Unit)
Those functions collect the flow and:
- Destroy its collection job on LifecycleOwner's
onPause()(collectWhileResumed/collectWhileResumedIn) oronStop()(collectWhileStarted/collectWhileStartedIn). - Recreates its collection job on LifecycleOwner's
onResume()(collectWhileResumed/collectWhileResumedIn) oronStart()(collectWhileStarted/collectWhileStartedIn).
The main motivation for this library is to have lifecycle-aware collectors much like those that can be launched with:
lifecycleScope.launchWhenStarted {
flow.collect { }
}The issue with the above approach is that if our flow is a SharedFlow<T>, paused collectors will still be subscribed collectors, so they will have no effect on SharedFlow's SharingStarted.WhileSubscribed() and SharedFlow<T>.subscriptionCount configurations.
On project-level build.gradle, add Jitpack repository:
allprojects {
repositories {
maven { url 'https://jitpack.io' }
}
}On app-level build.gradle, add dependency:
dependencies {
implementation 'com.github.psteiger:flow-lifecycle-observer:0.2.1'
}@AndroidEntryPoint
class NearbyUsersActivity : AppCompatActivity() {
private val viewModel: NearbyUsersViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
viewModel
.locations
.onEach { /* new locations received */ }
.collectWhileStartedIn(this)
viewModel
.users
.collectWhileStarted(this) {
/* new users received */
}
}
}