tezvyn:

Why is LiveData<Boolean> problematic for one-time ViewModel events?

Curated by the Tezvyn teamSource: developer.android.comintermediate
Why is LiveData<Boolean> problematic for one-time ViewModel events?
WHAT IT TESTS

LiveData replays one-time events after rotation.

A GOOD ANSWER COVERS

State is not events; suggest an Event wrapper with a consumed flag, or SharedFlow or Channel with no replay.

RED FLAG

Praising SingleLiveEvent or onCleared resets as fix.

WHAT THIS TESTS: This question probes your understanding of the difference between UI state and one-time UI events. LiveData is designed to hold state that persists across configuration changes, but events like showing a Snackbar or navigating to a new screen should happen exactly once. The interviewer wants to see if you recognize why a state-holding mechanism fails for ephemeral actions and whether you can name production-grade alternatives.

A GOOD ANSWER COVERS: First, explain the replay problem. When you post true to a LiveData<Boolean> from a ViewModel, the value survives rotation. The new Fragment observes the same ViewModel, and because LiveData delivers its latest value to new active observers, the true flag fires again, causing a duplicate Toast or navigation action. Second, clarify that state answers what the UI should look like right now, while an event answers what the UI should do once. Third, offer concrete solutions. The classic LiveData approach is an Event wrapper, a single-use data class with a handled Boolean flag and a getContentIfNotHandled method that returns the payload only on first read. In modern Kotlin code, the better path is often a SharedFlow with replay set to zero, or a Channel, both of which do not replay emissions to new collectors and naturally model one-time events. Fourth, mention that in Compose you collect these flows in a LaunchedEffect as a side effect rather than as state.

COMMON WRONG ANSWERS: A frequent mistake is proposing SingleLiveEvent as the perfect fix without acknowledging that it silently drops events when multiple observers are attached. Another red flag is suggesting that you reset the Boolean to false inside ViewModel.onCleared or immediately after observing it, because onCleared only runs when the ViewModel is truly destroyed, not on rotation, and manual resets race with the lifecycle. Some candidates also confuse the issue by suggesting you trigger the event from the Fragment directly, which breaks testability.

LIKELY FOLLOW-UPS: The interviewer may ask how you would test a one-time event flow, which should lead you to describe collecting the SharedFlow in a test coroutine and asserting exactly one value is emitted. They might also ask what happens after process death and restoration, pushing you to discuss whether the event should be saved in SavedStateHandle or treated as transient and lost. Another follow-up is how you would handle multiple simultaneous events, which invites a discussion about buffered channels or queues inside the ViewModel.

ONE CONCRETE EXAMPLE: Imagine a login screen where tapping a button calls viewModel.login. If the ViewModel exposes a LiveData<Boolean> called navigateToHome, setting it to true triggers navigation. After the user rotates the phone, the new Fragment observes the same ViewModel, sees true again, and navigates a second time. The fix is to expose a SharedFlow<Unit> named navigateToHomeEvents with replay set to zero. The Fragment collects this flow in a lifecycle-aware coroutine and calls findNavController.navigate once. On rotation, the new collector sees no replayed value, so navigation happens exactly once.

Read the original → developer.android.com

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.

Why is LiveData<Boolean> problematic for one-time ViewModel events? · Tezvyn