Kotlin Flows -What, Why and How?

Saurabh Pant
Dev Genius
Published in
4 min readJun 30, 2022

--

Glow with the Flow!!

As an Android Developer, we can’t escape the coroutine buzz around us. When it comes to coroutines, we often hit by another buzz alongside which we called as FLOWs in kotlin. As cool as it sounds, so does it functions. So why not to explore and know about these cool kotlin flows from basics.

In this article, we’ll try to answer following questions about the kotlin flows

  • What are Flow and what do they do?
  • Why should we use them?
  • How should we use them?
  • Cancellation basics
  • Transformation of flows

If you’re not flowing yet, its time to get started!

What are Flow and what do they do?

Flow is basically an emission of a sequence of some values. Yes, that’s what a flow is. Like we’ve LiveData, we’ve Flows. Though there are differences which we won’t cover here but you can start making an understanding of how flow works.

Consider a scenario in which we want to print some value sequence received one after the other after some computation without blocking the main thread. Let’s see how can we achieve it.

With regular function

example() function return a list of integers and here we get the output at once and this is synchronous. So this won’t full fill our need.

With Sequence

We modify our example function to return a sequence, with 1s wait for each value. Here we see that in the output the “main end” printed after all the values printed. It means this is also synchronous and we’ve to look for another work around.

With Suspend Function

Suspend functions are also regular function which operates sequentially within a coroutine scope until provided with suspended computation. So even this won’t help us.

With Flow

Now we modify our example() function to give us a flow. In the output we see that “main end” printed before flow collecting its values which shows that flow didn’t block our main thread and operating asynchronously.

Also, we noticed that now example() function is not a suspend function and it return immediately and we keep collecting the flow in async.

So that’s how flows are useful. They provide us support for asynchronous stream of values. We’ll see how we can do more with flows later in the article.

Why should we use them?

We can use flows in many scenarios specially when we’ve some background task is going on and it is emitting some data based on some states of the task and we need to react on those states.

Few scenarios where they can useful are as follows:

In UseCases

Consider making an api call where our UI updates based on the response from api call i.e. either we received an error or success or if the api call has begun and we need to display some loading UI. We’ve three different states here to capture so flow can be a good option here to use.

In Streaming apis

If we’re using some streaming apis and need to capture the events often then flow can come handy in such cases.

For Event or Data state

Types of flows like MutableSharedFlow, MutableStateFlow can be used for event and state update respectively for UI.

How should we use them?

By far, we’ve some basic understanding of What and Why of the flows. Now let’s understand the ‘How’ of flows.

First of all how to use a flow. Well! by simply writing code inside a flow builder or by converting any collection/sequence using asFlow().

Yes its that simple. Note here that the function is not suspended. It means the function returns immediately by giving us a flow to operate on.

Now interesting and important point here is that flow starts its execution only when it is collected i.e. until we set a collector for flows, they won’t begin their execution.

That is why flows are cold streams.

If we’ll collect the flow twice then it’ll emit the values again. Consider the code below:

Its output is:

Yeah! That’s cool. Let’s move further.

Cancellation basics

We know that coroutines follows the cooperative cancellation. In the same way flows also adhere to cooperation cancellation.

If you’re not aware of coroutines basics, then do give it a read here and here and you won’t be disappointed.

As we can see, once the time is up, the flow does not emit values and we get only one value within the time limit.

Transformation of flows

Flows can be transformed using operators like we’ve for collections and sequences. These operators applied on upstream flow and return a downstream flow. These operators are cold, just like flows are.

Consider this example where the flow is emitting 10 values but using operators on upstream, we’ve created a new downstream.

  • Filter operator filters out the values.
  • Map operator converts the int value to a string value with a delay of 1s.
  • Then finally collect prints the result.

One important thing to note in this is the operators are sequentially executing for each emitted value.

There are more operators that you can look for to create new flow from a given flow and this is what transformation of flow means.

Whoa! Now that we’ve some better understanding of flows in kotlin, it’s time to get started with flows. We’ll discuss more about flows in further articles but for now this is good enough.

In case you want to read about coroutines basics do checkout my articles here and here.

That is all for now! Stay tuned!

Connect with me on medium(if the content is helpful to you) or on github and subscribe to email to be in sync for further interesting topics on Android.

Until next time…

Cheers!

--

--

App Developer (Native & Flutter) | Mentor | Writer | Youtuber @_zaqua | Traveller | Content Author & Course Instructor @Droidcon | Frontend Lead @MahilaMoney