ခဏလေး ဒီလိုပဲ စဉ်းစားကြည့်
Coroutine က lightweight thread လိုမျိုးပါ — `suspend` function ကို `viewModelScope.launch { }` ထဲမှာ ခေါ်ရင် UI thread ကို block မလုပ်ဘဲ background မှာ run ပြီး, result ရလာရင် UI ကို update ပြန်ပေးပါတယ်။ Flow ကတော့ 'time ကြားထဲ value အများ ဆက်တိုက် ထုတ်ပေးတဲ့ stream' ကို ကိုယ်စားပြုပါတယ် (database query result auto-update, real-time search box) — Room DAO query ကို `Flow<List<TodoEntity>>` return type အနေနဲ့ ရေးထားရင်, database ထဲ data change ရင် UI ကို automatic update ပေးပါတယ်.
လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
`@Query("SELECT * FROM TodoEntity") fun getAllAsFlow(): Flow<List<TodoEntity>>` လို့ Room DAO မှာ ရေးထားရင် — todo item အသစ် insert လုပ်တာနဲ့ (တခြား code ကနေတောင်), ViewModel ထဲက `.collect { todos -> ... }` က automatic trigger ဖြစ်ပြီး UI ကို live update ပေးပါလိမ့်မယ် — manual refresh button လိုအပ်တော့ပါ.
အတူတူ ကြည့်မယ်
class TodoViewModel(private val dao: TodoDao) : ViewModel() {
val todos: StateFlow<List<TodoEntity>> = dao.getAllAsFlow()
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
initialValue = emptyList()
)
fun addTodo(title: String) {
viewModelScope.launch {
dao.insert(TodoEntity(id = UUID.randomUUID().toString(), title = title, isDone = false))
}
}
}`addTodo()` ခေါ်တာနဲ့ database update ဖြစ်ပြီး, UI ကို manual refresh မလိုဘဲ todos list က automatic update ဖြစ်နေတာ တွေ့ရမည်။၅ မိနစ် စမ်းကြည့်
Room DAO (Advanced lesson 3) ကို `Flow<List<TodoEntity>>` return အောင် ပြောင်းရေးကြည့်ပါ — todo item insert ပြီးတိုင်း UI ကို manual refresh မလိုဘဲ auto-update ဖြစ်တာ confirm လုပ်ကြည့်ပါ။
သတိလေးတစ်ချက်
`GlobalScope.launch { }` ကို production code မှာ မသုံးပါနှင့် — Coroutine ရဲ့ lifecycle ကို control မရနိုင်တော့ပြီး, memory leak/crash risk ရှိပါတယ်; `viewModelScope`/`lifecycleScope` ကို အမြဲသုံးပါ။