Lesson 6 of 8
Coroutines and Async Code
Learn coroutines, Kotlin's way of doing slow work such as network calls without freezing the app. code written with coroutines reads like ordinary step-by-step code.
import kotlinx.coroutines.*
// 'suspend' marks a function that can pause without
// blocking its thread:
suspend fun fetchUser(): String {
delay(1000) // pretend network call (non-blocking)
return "Ada"
}
suspend fun fetchScore(): Int {
delay(1000)
return 95
}
fun main() = runBlocking {
// Sequential — takes ~2 seconds:
val user = fetchUser()
val score = fetchScore()
println("$user: $score")
// Concurrent — takes ~1 second:
val userDeferred = async { fetchUser() }
val scoreDeferred = async { fetchScore() }
println("${userDeferred.await()}: ${scoreDeferred.await()}")
}delay() suspends the coroutine but frees the thread to do other work — unlike Thread.sleep(), which blocks it. launch starts a fire-and-forget coroutine; async starts one that returns a value you await. Structured concurrency means coroutines launched in a are cancelled with it — no leaked background work.
// The shape you'll write constantly in Android:
class ProfileViewModel : ViewModel() {
fun loadProfile() {
// viewModelScope dies with the screen — auto-cancel:
viewModelScope.launch {
val user = withContext(Dispatchers.IO) {
api.fetchUser() // network on IO threads
}
_uiState.value = UiState.Loaded(user) // back on main
}
}
}
// Dispatchers = which threads:
// Dispatchers.Main -> UI updates
// Dispatchers.IO -> network / disk
// Dispatchers.Default -> heavy computationFinished reading?Mark it done to track your progress.
Tip: use the ← and → keys to move between lessons.