📖 Scenario: You are building a simple Kotlin program that uses Flow to emit numbers. You want to change the thread where the flow runs using flowOn. This helps you run the flow on a background thread instead of the main thread.
🎯 Goal: Create a Kotlin Flow that emits numbers 1 to 3. Use flowOn to make the flow run on the Dispatchers.Default thread. Finally, collect and print the numbers on the main thread.
📋 What You'll Learn
Create a Flow that emits numbers 1, 2, and 3
Use flowOn(Dispatchers.Default) to change the dispatcher
Collect the flow and print each number
Use runBlocking to run the coroutine in main
💡 Why This Matters
🌍 Real World
Changing the dispatcher with flowOn is useful when you want to run heavy or blocking tasks on background threads without freezing the main UI thread.
💼 Career
Understanding flowOn is important for Kotlin developers working with asynchronous data streams and concurrency in Android or backend applications.
Progress0 / 4 steps
1
Create a Flow that emits numbers 1 to 3
Create a flow called numberFlow that emits the numbers 1, 2, and 3 using emit() inside the flow { } builder.
Kotlin
Hint
Use val numberFlow = flow { emit(1); emit(2); emit(3) } to create the flow.
2
Add flowOn to change dispatcher to Dispatchers.Default
Add flowOn(Dispatchers.Default) to numberFlow to make it run on the Default dispatcher. Assign the result back to numberFlow.
Kotlin
Hint
Use numberFlow = numberFlow.flowOn(Dispatchers.Default) or chain .flowOn(Dispatchers.Default) after the flow builder.
3
Collect the flow and print each number
Inside a runBlocking block, collect numberFlow using collect. For each emitted number, print it using println.
Kotlin
Hint
Use runBlocking { numberFlow.collect { number -> println(number) } } to collect and print.
4
Print the collected numbers as output
Run the program and observe the printed numbers 1, 2, and 3 each on its own line.
Kotlin
Hint
The program should print: 1 2 3
Practice
(1/5)
1. What does the flowOn operator do in Kotlin Flow?
easy
A. It collects the flow on the main thread.
B. It changes the thread where the flow is executed.
C. It cancels the flow immediately.
D. It buffers the flow emissions.
Solution
Step 1: Understand the role of flowOn
The flowOn operator changes the dispatcher where the upstream flow runs, allowing background work on a different thread.
Step 2: Differentiate from other flow operators
Unlike collection which runs on the original coroutine context, flowOn switches the execution context of the flow itself.
Final Answer:
It changes the thread where the flow is executed. -> Option B
Quick Check:
flowOn switches thread = B [OK]
Hint: Remember: flowOn changes flow thread, not collector thread [OK]
Common Mistakes:
Confusing flowOn with collect context
Thinking flowOn cancels the flow
Assuming flowOn buffers emissions
2. Which of the following is the correct syntax to apply flowOn to a flow named myFlow to run on Dispatchers.IO?
easy
A. myFlow.runOn(Dispatchers.IO)
B. myFlow.collectOn(Dispatchers.IO)
C. myFlow.flow(Dispatchers.IO)
D. myFlow.flowOn(Dispatchers.IO)
Solution
Step 1: Identify the correct function name
The operator to change the dispatcher of a flow is flowOn, not collectOn, flow, or runOn.
Step 2: Confirm the syntax usage
The correct syntax is calling flowOn on the flow instance with the dispatcher as argument.
Final Answer:
myFlow.flowOn(Dispatchers.IO) -> Option D
Quick Check:
Correct syntax = A [OK]
Hint: Use flowOn exactly as method name [OK]
Common Mistakes:
Using wrong method names like collectOn
Passing dispatcher incorrectly
Confusing flowOn with collect
3. What will be the output thread of the collector in this code snippet?
A. The collector runs on the original coroutine context thread.
B. The collector runs on the main thread regardless.
C. The collector runs on Dispatchers.IO thread.
D. The collector runs on a new thread created by flowOn.
Solution
Step 1: Understand flowOn effect on upstream
The flowOn(Dispatchers.IO) changes the thread where the flow builder runs, so emit runs on IO thread.
Step 2: Identify collector thread context
The collector runs on the coroutine context where collect is called, which is the original coroutine context unless changed explicitly.
Final Answer:
The collector runs on the original coroutine context thread. -> Option A
Quick Check:
Collector thread = original context = C [OK]
Hint: flowOn changes upstream thread, collector stays on original [OK]
Common Mistakes:
Assuming collector runs on flowOn dispatcher
Thinking flowOn creates new thread for collector
Confusing emit thread with collect thread
4. Identify the error in this Kotlin Flow code:
flow {
emit(1)
}.flowOn(Dispatchers.IO)
.collect { value ->
println(value)
}
medium
A. Missing coroutine scope to call collect.
B. flowOn cannot be used with emit.
C. collect must be called before flowOn.
D. Dispatchers.IO is not a valid dispatcher.
Solution
Step 1: Check coroutine context for collect
The collect function is a suspend function and must be called inside a coroutine or suspend function.
Step 2: Verify flowOn and emit usage
Using flowOn(Dispatchers.IO) with emit is correct; no error here.
Final Answer:
Missing coroutine scope to call collect. -> Option A
Quick Check:
collect needs coroutine scope = D [OK]
Hint: Always call collect inside coroutine or suspend function [OK]
Common Mistakes:
Thinking flowOn can't be used with emit
Calling collect outside coroutine
Misordering flowOn and collect
5. You want to perform a CPU-intensive calculation inside a flow and collect results on the main thread. Which is the correct way to use flowOn and collect to achieve this?
hard
A. Use collectOn(Dispatchers.Default) for calculation and flowOn(Dispatchers.Main) for collection.
B. Use flowOn(Dispatchers.Main) for calculation and collect on Default dispatcher.
C. Use flowOn(Dispatchers.Default) for calculation and collect on main thread.
D. Run calculation and collection both on Dispatchers.IO.
Solution
Step 1: Choose dispatcher for CPU-intensive work
CPU-intensive tasks should run on Dispatchers.Default to avoid blocking main thread.
Step 2: Use flowOn to switch flow execution thread
Applying flowOn(Dispatchers.Default) runs the flow builder on Default dispatcher.
Step 3: Collect on main thread
Collecting on main thread allows UI updates; no dispatcher change needed for collect.
Final Answer:
Use flowOn(Dispatchers.Default) for calculation and collect on main thread. -> Option C
Quick Check:
CPU work on Default, collect on main = A [OK]
Hint: Put heavy work in flowOn(Default), collect on main thread [OK]
Common Mistakes:
Using flowOn(Main) for heavy work
Confusing flowOn with collectOn
Running CPU work on IO dispatcher
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.