Creating Flow Using Flow Builder in Kotlin

Authors
Creating Flow Using Flow Builder in Kotlin

In Kotlin, we can create a Flow using four types of flow builders: flowOf(), asFlow(), flow{}, and channelFlow{}.

In this blog, we are going to discuss the different types of flow builders and how to create Flow using Flow Builder. We will learn to create Flow with examples.

This blog is a part of the series I have written on Flow API in Kotlin:

I am Amit Shekhar, Founder @ Outcome School, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

I teach AI and Machine Learning, and Android at Outcome School.

Join Outcome School and get a high-paying tech job:

Let's get started.

We are going to cover the following:

  • Types of flow builders
  • Creating Flow Using Flow Builder

Types of flow builders

There are 4 types of flow builders:

  1. flowOf(): It is used to create flow from a given set of items.
  2. asFlow(): It is an extension function that helps to convert type into flows.
  3. flow{}: This is what we have used in the Hello World example of Flow.
  4. channelFlow{}: This builder creates flow with the elements using send provided by the builder itself.

Examples:

flowOf()

flowOf(4, 2, 5, 1, 7)
.collect {
    Log.d(TAG, it.toString())
}

asFlow()

(1..5).asFlow()
.collect {
    Log.d(TAG, it.toString())
}

flow{}

flow {
    (0..10).forEach {
        emit(it)
    }
}
.collect {
    Log.d(TAG, it.toString())
}

channelFlow{}

channelFlow {
    (0..10).forEach {
        send(it)
    }
}
.collect {
    Log.d(TAG, it.toString())
}

Now, we will learn how to create our Flow using the Flow builder. We can create our Flow for any task using the Flow Builder.

A quick note for you

No matter which tech domain you work in, get familiar with these topics:

  • LLM
  • RAG
  • MCP
  • Agent
  • Fine-tuning
  • Quantization

We put it all together in one video:

AI Engineering Explained: LLM, RAG, MCP, Agent, Fine-Tuning, and Quantization

No need to stop reading - bookmark it and watch later when you get time. Future you will thank you.

Now, let's get back to the topic.

Creating Flow Using Flow Builder

Let's learn it through examples.

1. Move File from one location to another location

Here, we will create our Flow using the Flow Builder for moving the file from one location to another in the background thread and send the completion status on Main Thread.

val moveFileflow = flow {
        // move file on background thread
        FileUtils.move(source, destination)
        emit("Done")
}
.flowOn(Dispatchers.IO)
CoroutineScope(Dispatchers.Main).launch {
    moveFileflow.collect {
        // when it is done
    }
}

2. Downloading an Image

Here, we will create our Flow using the Flow Builder for downloading the Image which will download the Image in the background thread and keep sending the progress to the collector on the Main thread.

val downloadImageflow = flow {
        // start downloading
        // send progress
        emit(10)
        // downloading...
        // ......
        // send progress
        emit(75)
        // downloading...
        // ......
        // send progress
        emit(100)
}
.flowOn(Dispatchers.IO)
CoroutineScope(Dispatchers.Main).launch {
    downloadImageflow.collect {
        // we will get the progress here
    }
}

This is how we can create our Flow.

To master Flow builders, cold and hot flow, terminal operators, StateFlow, and SharedFlow hands-on while building real Android apps, check out the Android Program by Outcome School.

Frequently Asked Questions

What is the difference between flow and channelFlow builders?

In the flow{} builder, we produce values using emit(). The channelFlow{} builder creates the flow with the elements using send(), which is provided by the builder itself. Both are collected in the same way using collect.

When should we use flowOf instead of asFlow?

We use flowOf() when we want to create a flow from a given set of items, like flowOf(4, 2, 5, 1, 7). We use asFlow() when we want to convert an existing type into a flow, like (1..5).asFlow(), because it is an extension function.

How do we run the work of a Flow on a background thread?

We add .flowOn(Dispatchers.IO) to the flow. The work inside the flow builder, like moving a file or downloading an image, then runs on the background thread. We collect the flow inside a coroutine launched on Dispatchers.Main to get the result on the Main thread.

Can a Flow send progress updates while a task is running?

Yes. We can call emit() many times inside the flow builder. For example, while downloading an image, we emit 10, then 75, then 100 as the progress. The collector on the Main thread gets each progress value as it is emitted.

That's it for now.

Thanks

Amit Shekhar
Founder @ Outcome School

You can connect with me on:

Follow Outcome School on:

Read all of our high-quality blogs here.

Subscribe to our newsletter to get our latest AI and Machine Learning blogs straight to your inbox.