Skip to content

Commit 3bbb625

Browse files
authored
Wrap subscription action with lifecycle whenStarted (#665)
* Wrap subscription action with lifecycle `whenStarted` The specifics of behaviour of `flowWhenStarted` implementation implicitly used in resolve subscription will allow submitted action to resume continuation even if lifecycle is moved into stopped state. For example: ``` // Fragment override fun onCreate(savedInstanceState: Bundle?) { viewModel.onEach(ViewState::isVisible) { isVisible -> ... binding.someview.reveal() // (1) suspendable, performs animation binding.someview.text = "" // (2) touches other UI after continuation ... } } ``` Users can observe crash in above example if lifecycle of view moved into stopped state while coroutine was suspended at (1) suspension point. The reason is that submitted action via `onEach` won't be paused / canceled when reached suspension point and lifecycle moved into stopped state (see implementations of `collectLatest` and `flowWhenStarted` together). The recommendation was to wrap submitted `onEach` action into `whenStarted` on the user side to make coroutine paused when lifecycle is stopped. But why not change this on mavericks side and address this issue at the core?
1 parent 2640899 commit 3bbb625

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

mvrx/src/main/kotlin/com/airbnb/mvrx/FlowExtensions.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package com.airbnb.mvrx
33
import androidx.lifecycle.DefaultLifecycleObserver
44
import androidx.lifecycle.LifecycleOwner
55
import androidx.lifecycle.lifecycleScope
6+
import androidx.lifecycle.whenStarted
67
import kotlinx.coroutines.CoroutineStart
78
import kotlinx.coroutines.Job
89
import kotlinx.coroutines.flow.Flow
@@ -41,7 +42,13 @@ internal fun <T : Any?> Flow<T>.collectLatest(
4142
// This is necessary when Dispatchers.Main.immediate is used in scope.
4243
// Coroutine is launched with start = CoroutineStart.UNDISPATCHED to perform dispatch only once.
4344
yield()
44-
flow.collectLatest(action)
45+
flow.collectLatest {
46+
if (MavericksTestOverrides.FORCE_DISABLE_LIFECYCLE_AWARE_OBSERVER) {
47+
action(it)
48+
} else {
49+
lifecycleOwner.whenStarted { action(it) }
50+
}
51+
}
4552
}
4653
}
4754

0 commit comments

Comments
 (0)