Sharing Flows & Lifecycle-Safe Collection Flashcards
KOTLIN › Flow
- What problem do stateIn and shareIn solve?
- A cold flow re-runs its producer for every collector, so two collectors means two queries. They convert it to a single hot upstream that many collectors observe, sharing one execution.
- What is the difference between stateIn and shareIn?
- stateIn produces a StateFlow, so it always has a current value and demands an initialValue. shareIn produces a SharedFlow, which has no required current value and suits events rather than state.
- What do the three SharingStarted policies do?
- Eagerly starts the upstream at once and never stops it. Lazily starts on the first subscriber and never stops. WhileSubscribed(t) starts on the first subscriber and stops t milliseconds after the last one leaves.
- Why is WhileSubscribed(5_000) the conventional value?
- It straddles two lifecycle events: a configuration change completes well inside 5 seconds so the upstream survives rotation with no re-query, while backgrounding lasts far longer so resources are actually released.
- What does replayExpirationMillis control?
- How long the cached value survives after the upstream stops. The default keeps it forever, so returning to a screen shows the last known state immediately. Zero drops the cache, so a returning subscriber gets the initial value again.
- What is wrong with calling stateIn inside a function?
- Every call builds a new shared flow with its own upstream, so each caller triggers its own query and nothing is shared. It has to be a property, created once.
- Why was launchWhenStarted deprecated?
- It suspends the collector rather than cancelling it, so the subscription stays active and the upstream keeps producing while backgrounded. WhileSubscribed never sees the subscriber leave, so it never stops either.
- What is the one-sentence relationship between repeatOnLifecycle and WhileSubscribed?
- repeatOnLifecycle cancels the subscription so that WhileSubscribed can stop the producer. Both halves are required: either one alone leaves the upstream running in the background.
- Why prefer collectAsStateWithLifecycle over collectAsState on Android?
- Because a backgrounded Activity does not leave composition, so collectAsState keeps collecting the whole time the app is in the background. The lifecycle-aware variant wraps repeatOnLifecycle and stops below STARTED.
- In a Fragment, why use viewLifecycleOwner.lifecycleScope rather than lifecycleScope?
- Because the Fragment scope lives until onDestroy while the view dies at onDestroyView. A collector on the Fragment scope keeps rendering into a released binding, which crashes or leaks the view.
- How should you collect several flows in one Fragment?
- One repeatOnLifecycle block containing a launch per flow. Each repeatOnLifecycle call is its own coroutine with its own overhead, so one per flow is wasteful.
- Why is repeatOnLifecycle(STARTED) the recommended way to collect a flow in a View/Activity?
- It starts collection when the lifecycle reaches STARTED and cancels the whole coroutine at STOPPED, fully tearing down the upstream producer when the UI is not visible, then restarts it on return. It avoids both crashes and wasted background work.
- What does .stateIn(scope, SharingStarted.WhileSubscribed(5000), initialValue) give you?
- It converts a cold flow into a hot StateFlow scoped to (typically) viewModelScope. WhileSubscribed(5000) keeps the upstream alive for 5s after the last collector leaves, so it survives configuration changes without restarting the producer on quick rotations.