The main (UI) thread must stay free, or the app freezes ("ANR"). Coroutines let you write asynchronous code that looks synchronous.
suspend functions
A suspend function can pause without blocking the thread. You call it from a coroutine scope.
suspend fun loadData(): List<Item> = withContext(Dispatchers.IO) {
// heavy work runs on a background thread
repository.fetchAll()
}
Launching coroutines
viewModelScope.launch {
val items = loadData() // suspends, doesn't block UI
_state.value = items // back on main thread
}
Dispatchers
Dispatchers.Main— UI work.Dispatchers.IO— network & disk.Dispatchers.Default— heavy CPU work.
Tip: Use
viewModelScope / lifecycleScope so coroutines auto-cancel when the screen goes away.Summary
Coroutines keep the UI smooth. Do heavy work on IO/Default dispatchers and update state on Main.