Hot vs. Cold Streams: StateFlow vs. Flow in Android

This tests your grasp of stream lifecycles. A great answer defines cold Flow (lazy, per-collector) vs. hot StateFlow (active, shared state) and uses a ViewModel UI state scenario. A red flag is mischaracterizing a Flow as a one-time operation.
What's really being asked
This question tests your fundamental understanding of reactive stream lifecycles and resource management. The interviewer wants to see if you can differentiate between data streams that are created on-demand (cold) versus those that are always active and broadcasting (hot). It specifically probes your ability to apply this knowledge to the most common Android architecture pattern: managing UI state from a ViewModel.
The full answer
An excellent answer addresses four points in order. First, define a cold stream (Flow) as lazy; it's a blueprint for work that only executes when a terminal operator like collect is called, and each collector triggers a new, independent execution. Second, define a hot stream (StateFlow/SharedFlow) as active and shared; it exists and can emit values even with zero collectors. Third, detail the specific characteristics of StateFlow: it always has a value, replays the most recent value to new collectors, and is designed for representing state. Finally, provide the canonical Android scenario: a ViewModel exposing UI state to the View. StateFlow is ideal here because the View needs the current state immediately upon observing, especially after a configuration change like screen rotation, without re-triggering the data fetch logic.
The mistakes people make
A common mistake is describing a cold Flow as being for "one-time operations." A suspend function is for a one-time operation; a Flow is for a stream of zero-to-many values, it's just a lazy one. Another red flag is not being able to articulate why a cold flow is wrong for UI state. The key issue is that a new collection (e.g., after rotation) would re-execute the entire upstream flow, potentially re-triggering network requests or database queries unnecessarily. Finally, candidates often conflate StateFlow with LiveData without explaining the key differences (e.g., StateFlow is not lifecycle-aware and requires a coroutine scope for collection).
What usually comes next
Be prepared for: "When would you use a SharedFlow instead of a StateFlow?" (Answer: for events that should be consumed once and not replayed to new collectors, like showing a Toast or navigating). Also, "How is StateFlow implemented in terms of SharedFlow?" (Answer: It's conceptually similar to a SharedFlow with replay = 1, onBufferOverflow = DROP_OLDEST, and an initial value). Finally, "How do you safely collect a flow from the UI layer?" (Answer: Using viewLifecycleOwner.lifecycleScope.launch with repeatOnLifecycle(Lifecycle.State.STARTED)).
A concrete example
In a ViewModel for a user profile screen, you would expose the UI state using StateFlow. For example: private val _uiState = MutableStateFlow(ProfileUiState(isLoading = true)) and val uiState: StateFlow<ProfileUiState> = _uiState.asStateFlow(). The ProfileUiState data class would contain fields like isLoading, userName, and error. When the corresponding Fragment or Composable collects uiState, it immediately receives the current state. If the user rotates the screen, the new UI instance subscribes and gets the exact same last-emitted state without causing the ViewModel to re-fetch the user profile from the network.
Interview question
Why is StateFlow generally preferred over a regular Flow for exposing UI state from an Android ViewModel?
- a.StateFlow is inherently lifecycle-aware, automatically managing collection based on the Android component's lifecycle.
- b.It always holds a current value, replays it to new collectors immediately, and prevents re-execution of upstream logic on re-collection.Correct
- c.StateFlow consumes fewer resources because it only emits values when the UI is actively observing.
- d.StateFlow is designed for single, one-time UI events, while Flow is for continuous data streams.
Why? this is the answer
StateFlow is ideal for UI state because it always maintains a current value, immediately provides this value to new observers, and critically, avoids re-triggering the entire data stream (e.g., network calls) when the UI re-collects, such as after a screen rotation. Option A is a common misconception, as StateFlow is not inherently lifecycle-aware and requires explicit scope management for collection.
Just read this? Test yourself on what you have been reading.
Read the original → developer.android.com
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on kotlin — each one lists the topics its interview covers.
See open roles