0
0
KotlinHow-ToBeginner · 3 min read

How to Create Flow in Kotlin: Simple Guide with Examples

In Kotlin, you create a Flow by using the flow { } builder which emits values asynchronously. You can collect these values using the collect function inside a coroutine to handle the data stream.
📐

Syntax

The basic syntax to create a Flow uses the flow { } builder. Inside the braces, you use emit() to send values one by one. To receive these values, you call collect on the flow inside a coroutine.

  • flow { }: Creates the flow.
  • emit(value): Sends a value to the flow.
  • collect { }: Receives values from the flow.
kotlin
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

fun simpleFlow(): Flow<Int> = flow {
    emit(1)  // send first value
    emit(2)  // send second value
    emit(3)  // send third value
}

fun main() = runBlocking {
    simpleFlow().collect { value ->
        println(value)
    }
}
Output
1 2 3
💻

Example

This example shows how to create a flow that emits numbers from 1 to 5 with a delay between each emission. It demonstrates asynchronous data streaming and collection.

kotlin
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

fun numberFlow(): Flow<Int> = flow {
    for (i in 1..5) {
        delay(100)  // simulate work
        emit(i)    // emit next number
    }
}

fun main() = runBlocking {
    numberFlow().collect { value ->
        println("Received $value")
    }
}
Output
Received 1 Received 2 Received 3 Received 4 Received 5
⚠️

Common Pitfalls

One common mistake is trying to collect a flow outside of a coroutine, which causes a compiler error because collect is a suspend function. Another is forgetting to use emit inside the flow { } builder, resulting in an empty flow.

Also, blocking the main thread inside the flow builder can freeze your app; always use suspend functions like delay instead of Thread.sleep.

kotlin
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.runBlocking

// Wrong: collect called outside coroutine
// val flow = flow { emit(1) }
// flow.collect { println(it) } // Error: suspend function

// Right way:
fun main() = runBlocking {
    val flow = flow { emit(1) }
    flow.collect { println(it) }
}
Output
1
📊

Quick Reference

ConceptDescription
flow { }Builder to create a flow emitting values asynchronously
emit(value)Sends a value to the flow stream
collect { }Suspending function to receive emitted values
runBlockingStarts a coroutine to run suspend functions in main
delay(time)Suspends coroutine without blocking thread

Key Takeaways

Use the flow { } builder and emit() to create asynchronous data streams in Kotlin.
Always collect flow values inside a coroutine using collect { }.
Never call collect outside a coroutine; it is a suspend function.
Use suspend functions like delay() inside flows to avoid blocking the thread.
Flows are cold streams; they start emitting only when collected.