6

I'm trying to observe the result of the View Collection and upstream flows stopped. But viewModel.testFlow is still collecting while the App is in the background. Why can't I observe the collection is stopped? Am I observing something wrong?

ViewModel:

val testFlow = flow<Int> {
    for (i in 1..100) {
        delay(1000)
        Timber.e("testFlow: EMIT = $i")
        emit(i)
    }
}

Activity:

override fun onViewCreated() {
        lifecycleScope.launch {
            viewModel.testFlow
                .flowWithLifecycle(lifecycle, Lifecycle.State.STARTED)
                .collect {
                    Timber.d("testFlow: $it Collected")
                }
        }
}

override fun onActivityPaused(activity: Activity) {
    super.onActivityPaused(activity)
    Timber.e("testFlow: onActivityPaused")
}

Logs Lifecycle Diagram

https://medium.com/androiddevelopers/a-safer-way-to-collect-flows-from-android-uis-23080b1f8bda

Orcun Sevsay
  • 1,310
  • 1
  • 14
  • 44

3 Answers3

2

You are using Lifecycle.State.STARTED state to start observing Flow, the corresponding method of the Activity when emission stops is onStop(). If onStop() method of Activity is called the emission and collecting will stop.

If you want to stop emitting and collection data when onPause method is called, you can use Lifecycle.State.RESUMED state.

When app goes to background onStop() method of Activity is called and when using Lifecycle.State.STARTED state to observe the Flow you should see the emission and collecting stop.

Sergio
  • 27,326
  • 8
  • 128
  • 149
0

you can handle another way with repeatOnLifecycle

lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED){
            viewModel.stateLocationPermission.collect() {
                handleStateLocationPermission(it)
            }
        }
    }
0

You can make use of this extension:

fun <T> Flow<T>.collectLifecycleAware(
    owner: LifecycleOwner,
    flowCollector: FlowCollector<T>,
) {
    owner.lifecycleScope.launch {
        this@collectLifecycleAware.flowWithLifecycle(owner.lifecycle)
            .collect(flowCollector)
    }
}

And use it as:

state.collectLifecycleAware(viewLifecycleOwner) { state ->
    ...
}

Also, you'll need:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:<latest-version>"
Yasser AKBBACH
  • 539
  • 5
  • 7