Cả hai đều giữ giá trị hiện tại và báo cho observer khi giá trị đổi, nhưng khác gốc: LiveData là class của Android, lifecycle-aware sẵn; StateFlow thuộc Kotlin coroutines, không phụ thuộc Android.
| LiveData | StateFlow | |
|---|---|---|
| Giá trị ban đầu | Không bắt buộc (có thể null) | Bắt buộc |
| Lifecycle | Tự ngừng gửi khi observer dưới STARTED | Không tự biết; phải collect trong repeatOnLifecycle |
| Toán tử | Ít (map, switchMap) | Toàn bộ operator của Flow (combine, debounce, flatMapLatest...) |
| Giá trị trùng | Vẫn phát lại | Bỏ qua nếu equals giá trị cũ |
| Dùng ngoài Android | Không | Có (domain layer, KMP) |
kotlin
// ViewModel
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState.asStateFlow()
// Compose
val state by viewModel.uiState.collectAsStateWithLifecycle()
// Fragment
viewLifecycleOwner.lifecycleScope.launch {
viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.uiState.collect { render(it) }
}
}Code mới thường chọn StateFlow vì dùng một kiểu xuyên suốt từ data layer tới UI và hợp với Compose. LiveData không bị deprecate, vẫn ổn trong dự án cũ dùng View/XML.
Lưu ý: collect StateFlow bằng lifecycleScope.launch trần (không có repeatOnLifecycle) sẽ tiếp tục chạy khi app ở nền — tốn tài nguyên và có thể cập nhật view đã bị huỷ. StateFlow cũng không hợp cho sự kiện một lần (điều hướng, toast) vì nó giữ giá trị cuối và bỏ qua giá trị trùng.