Thuta Learning
AdvancedMobile Developmentintermediate

Kotlin Coroutines & Flow

Relax. We'll talk through this in plain words — no textbook voice.

What you'll walk away with

  • Understand Kotlin Coroutines & Flow without the intimidation
  • Get comfortable running Android Studio/Compose code yourself
  • Apply this concept in a real project right away

Let's think about it this way for a second

A Coroutine is basically a lightweight thread — calling a `suspend` function inside `viewModelScope.launch { }` runs it in the background without blocking the UI thread, then updates the UI once the result comes back. Flow represents 'a stream that keeps emitting values over time' (an auto-updating database query result, a real-time search box) — write a Room DAO query with a `Flow<List<TodoEntity>>` return type and the UI updates automatically whenever the underlying data changes.

Let's connect this to a real scenario

If you write `@Query("SELECT * FROM TodoEntity") fun getAllAsFlow(): Flow<List<TodoEntity>>` in your Room DAO — whenever a new todo item gets inserted (even from other code), the `.collect { todos -> ... }` in your ViewModel triggers automatically and live-updates the UI — no manual refresh button needed.

Let's walk through it together

kotlin
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))
        }
    }
}
You should see
Calling `addTodo()` should update the database, and you should see the todos list update automatically without needing a manual UI refresh.

5-minute try-it

Rewrite the Room DAO (Advanced lesson 3) to return `Flow<List<TodoEntity>>` — confirm that inserting a todo item auto-updates the UI without a manual refresh.

A quick word of caution

Don't use `GlobalScope.launch { }` in production code — you lose control over the Coroutine's lifecycle, risking memory leaks/crashes; always use `viewModelScope`/`lifecycleScope` instead.

Easy traps

  • Trying to call a `suspend` function directly outside a Coroutine scope (`viewModelScope.launch`) — this causes a compile error
  • Not cancelling/cleaning up after collecting a Flow — this can cause a memory leak (using viewModelScope auto-cancels it when the ViewModel is cleared)

Now try it yourself

Rewrite the Room DAO (Advanced lesson 3) to return `Flow<List<TodoEntity>>` — confirm that inserting a todo item auto-updates the UI without a manual refresh.

You'll know it worked when: Calling `addTodo()` should update the database, and you should see the todos list update automatically without needing a manual UI refresh.

Kotlin Coroutines & Flow | Thuta Learning