โ† all topics01 / 05 ยท learn android

๐ŸŒ€ 01 ยท learn android

Kotlin Coroutines

Concurrency without the thread-per-task tax

Lightweight threads that make async code read top-to-bottom.

A coroutine is Kotlin's answer to a problem that predates Kotlin: asynchronous work โ€” a network call, a disk read, a timer โ€” doesn't fit the synchronous "do this, then this" shape most code is written in. The old ways were callbacks (nested, error-prone) and threads (heavy, expensive, dangerous to coordinate). Coroutines are a third way: a block of code that can pause at a suspension point and resume later, without holding a thread hostage while it waits.

The mental model to hold onto: a coroutine is not a thread. It's a lightweight unit of work that runs on a thread, can be moved between threads, and โ€” critically โ€” can suspend, freeing its thread to run something else. You can have thousands of coroutines on a handful of threads, where thousands of threads would collapse under their own weight.

The mental model

How it fits together

Dispatchers โ€” which thread

Main ยท UI
IO ยท blocking I/O
Default ยท CPU

Structured concurrency โ€” the tree

CoroutineScope (viewModelScope)

โ†“

launch { โ€ฆ }

suspend โ†’ resume

async { โ€ฆ }

await() โ†’ result

cancel the scope โ†’ every child is cancelled

Key concepts

The ideas to internalise

suspend

A suspend function can pause and resume without blocking a thread. It carries a hidden continuation that remembers where it paused and what its locals were.

launch vs async

launch fires a coroutine and forgets it; async fires one and hands back a Deferred you await for a result. Fire-and-forget vs. get-a-result.

Dispatchers

Decide which thread a coroutine runs on โ€” Main for UI, IO for blocking I/O, Default for CPU-bound work.

Structured concurrency

Work is a tree. Cancel the scope and every child is cancelled; a child's failure is reported to its parent. No orphaned coroutines.

Scopes

viewModelScope and lifecycleScope tie work to a screen's lifetime and auto-cancel it when the screen dies.

Cooperative cancellation

A coroutine checks a cancellation flag at every suspension point. A tight non-suspending loop must call yield() or ensureActive() to be cancellable.

Example index

11 runnable examples

Each is a self-contained Activity + ViewModel pair you can open, read, and run.

  1. 01Single Network Callthe simplest coroutine network call
  2. 02Series Network Callstwo calls where the second depends on the first
  3. 03Parallel Network Callsindependent calls running concurrently via async + awaitAll
  4. 04Room DB Operationcoroutines with Room
  5. 05Long Running Taska background task off the main thread
  6. 06Two Long Running Taskstwo tasks in parallel
  7. 07TimeoutwithTimeout โ€” cancelling a task past a deadline
  8. 08Try-Catch Error Handlingcatching exceptions inside a coroutine
  9. 09CoroutineExceptionHandlercentralized error handling
  10. 10Ignore Error & ContinuesupervisorScope โ€” one failure doesn't kill siblings
  11. 11Unit Testtesting a coroutine-based ViewModel

The takeaway

Series vs parallel is the same operation with a different structure: withContext back-to-back waits for each call; async + awaitAll runs them together. The choice is simply which structure you write โ€” and structured concurrency guarantees the tree of work is torn down with its owner.