flowWithLifecycle(lifecycle, Lifecycle.State.STARTED) doesn't stop flows while App is in background
Asked Answered
H

3

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

Hungnam answered 6/1, 2022 at 12:1 Comment(1)
Where did you get the lifecycle variable for your flowWithLifecycle?Prana
S
3

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.

Swithbert answered 6/1, 2022 at 12:13 Comment(0)
M
0

you can handle another way with repeatOnLifecycle

lifecycleScope.launch {
        repeatOnLifecycle(Lifecycle.State.STARTED){
            viewModel.stateLocationPermission.collect() {
                handleStateLocationPermission(it)
            }
        }
    }
Moneybag answered 22/5, 2023 at 18:55 Comment(0)
S
0

You can make use of this extension:

fun <T> Flow<T>.collectLifecycleAware(
    owner: LifecycleOwner,
    flowCollector: FlowCollector<T>,
) {
    owner.lifecycleScope.launch {
        [email protected](owner.lifecycle)
            .collect(flowCollector)
    }
}

And use it as:

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

Also, you'll need:

implementation "androidx.lifecycle:lifecycle-runtime-ktx:<latest-version>"
Sanctum answered 21/6, 2023 at 14:2 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.