LiveData vs StateFlow

LiveData is lifecycle-aware by design and remains useful in View-based applications. StateFlow integrates with coroutines, exposes a required initial value and supports the full Flow operator ecosystem.

Practical guidance

  • Prefer StateFlow for new coroutine-based ViewModels.
  • Use collectAsStateWithLifecycle in Compose.
  • Use repeatOnLifecycle in Views and fragments.
  • Migrate at feature boundaries rather than rewriting stable screens without benefit.

Working example

val uiState: StateFlow<UiState> = repository.users
    .map<List<User>, UiState> { UiState.Content(it) }
    .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5_000), UiState.Loading)

// Compose
val state by viewModel.uiState.collectAsStateWithLifecycle()

Common mistakes

  • Plain collect in onCreate can update a stopped UI.
  • StateFlow requires an honest initial state.
  • Converting repeatedly between LiveData and Flow obscures ownership.

Key takeaway

Both can be correct. StateFlow is the stronger default when the rest of the feature already uses suspending APIs and Flow transformations.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top