Migrate từ LiveData sang StateFlow trong Android: Hướng dẫn thực tế cho dự án production
"StateFlow là tương lai. Nhưng migrate từ LiveData như thế nào để không phá vỡ architecture hiện tại?"

Mở đầu
Nếu bạn đang maintain một Android project cũ, rất có thể bạn đang có:
ViewModel + LiveData + XML
Và giờ team muốn migrate sang:
ViewModel + StateFlow + Compose (hoặc XML)
Câu hỏi là:
- có cần rewrite toàn bộ không?
- migrate từng phần được không?
- có rủi ro gì?
Tin tốt:
Bạn hoàn toàn có thể migrate incremental.
Không cần rewrite toàn bộ app.
1. Vì sao nên migrate?
Google hiện ưu tiên:
- Kotlin Coroutines
- Flow
- StateFlow
Nguồn:
https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
Lý do:
✅ coroutine-native
✅ tốt hơn cho Compose
✅ mạnh hơn về reactive stream
✅ dễ scale hơn cho architecture lớn
2. Một project LiveData thường trông như thế này
Ví dụ:
class UserViewModel : ViewModel() {
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
fun loadUsers() {
_users.value = repository.getUsers()
}
}
UI observe:
viewModel.users.observe(viewLifecycleOwner) {
adapter.submitList(it)
}
Hoạt động tốt.
Nhưng bị giới hạn:
- không coroutine-first
- khó combine stream
- khó test hơn
3. Step 1: thay MutableLiveData bằng MutableStateFlow
Trước:
private val _users = MutableLiveData<List<User>>()
val users: LiveData<List<User>> = _users
Sau:
private val _users =
MutableStateFlow<List<User>>(emptyList())
val users: StateFlow<List<User>> = _users
Lưu ý:
StateFlow bắt buộc có initial value.
Ví dụ:
emptyList()
false
UiState()
null
4. Step 2: thay .value
Trước:
_users.value = repository.getUsers()
Sau:
_users.value = repository.getUsers()
Tin vui:
cú pháp gần như giống hệt.
Đây là lý do migrate khá dễ.
5. Step 3: update UI layer
Trước:
viewModel.users.observe(
viewLifecycleOwner
) {
adapter.submitList(it)
}
Sau:
viewLifecycleOwner.lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED) {
viewModel.users.collect {
adapter.submitList(it)
}
}
}
Quan trọng:
Luôn dùng:
repeatOnLifecycle()
để tránh memory leak.
Google khuyến nghị cách này.
6. Với Jetpack Compose thì còn dễ hơn
val users by viewModel.users
.collectAsState()
Done.
Không cần observe.
Đây là lý do StateFlow cực hợp với Compose.
7. Nếu đang dùng XML thì sao?
Không cần migrate UI ngay.
Bạn có thể bridge:
val usersLiveData =
users.asLiveData()
Ví dụ:
private val _users =
MutableStateFlow<List<User>>(emptyList())
val usersLiveData =
_users.asLiveData()
UI cũ vẫn dùng:
observe()
=> migrate dần từng màn.
Đây là chiến lược tốt nhất cho production app.
8. Handling Loading + Error tốt hơn
LiveData thường viết:
val loading = MutableLiveData<Boolean>()
val users = MutableLiveData<List<User>>()
val error = MutableLiveData<String>()
Rất dễ rối.
StateFlow nên dùng:
data class UiState(
val loading: Boolean = false,
val users: List<User> = emptyList(),
val error: String? = null
)
ViewModel:
private val _uiState =
MutableStateFlow(UiState())
Ưu điểm:
✅ clean hơn
✅ scalable hơn
✅ dễ test hơn
9. Các lỗi migrate phổ biến
Lỗi 1: quên initial value
Sai:
MutableStateFlow<List<User>>()
Sẽ compile fail.
Phải là:
MutableStateFlow(emptyList())
Lỗi 2: quên repeatOnLifecycle
Sai:
launch {
flow.collect { }
}
Có thể gây leak.
Đúng:
repeatOnLifecycle(...)
Lỗi 3: migrate tất cả cùng lúc
Không nên.
Hãy migrate theo module:
Auth
→ Home
→ Profile
→ Settings
An toàn hơn nhiều.
10. Strategy migrate production
Mình khuyến nghị:
Phase 1
Repository trả về Flow
Phase 2
ViewModel đổi sang StateFlow
Phase 3
UI vẫn dùng asLiveData()
Phase 4
Migrate UI sang collect()
Phase 5
Remove LiveData hoàn toàn
Đây là cách ít rủi ro nhất.
11. Recommendation 2026
Nếu app mới:
StateFlow + SharedFlow
Nếu app cũ:
Migrate từng bước
Không rewrite toàn bộ.
Kết luận
Migrate từ LiveData sang StateFlow:
❌ không khó
❌ không cần rewrite app
Chỉ cần:
- đúng strategy
- migrate từng bước
- test kỹ từng màn
Đó là cách production team thực tế đang làm.
References
1. Android Developers — StateFlow and SharedFlow
https://developer.android.com/kotlin/flow/stateflow-and-sharedflow
2. Android Developers — LiveData
https://developer.android.com/topic/libraries/architecture/livedata
3. Official Kotlin Coroutines
All rights reserved