Kotlin Flow Basics - Part 1

Kotlin Flow is a new JetBrains Stream Processing library built on top of Kotlin Coroutines. Its main goal is to provide a standard for asynchronous streaming. Just like in RxJava, with Kotlin Flow you can manipulate and transform the flow of data in a multi-threaded way. 

Kotlin Flow vs Coroutines 

Unlike Coroutines where you can only return a single value; in Kotlin Flow you can return multiple values in an asynchronous manner without having to worry about switching between threads. 

 

Channels 

Streaming APIs are the exact opposite of REST APIs. When you do a request using a REST API, you get a response, but a Streaming API works differently, it connects to a client and listens for new information. Coroutines provides us with Channels. These Channels are some sort of hot stream pipes where you send values from one end and return the values on the other end. 

 

Hot vs. Cold Streams 

A channel, which is a hot stream, will produce values even if they aren’t listening to them on the other side. And if you are not listening to the stream, you are losing values. The channel is still producing the items, even when no one is listening: 

 

The above case can lead us to memory leaks.

The above case can lead us to memory leaks.

Kotlin Flow Basics 

Flow is a stream that produces values asynchronously. Furthermore, Flow uses coroutines internally. And because of this, it enjoys all the perks of  structured concurrency. With structured concurrency, coroutines live for a limited amount of time. This time is connected to the  CoroutineScope  you start your coroutines in. When you cancel the scope, you also release any running coroutines. The same rules apply to Kotlin Flow as well. When you cancel the scope, you also dispose of the Flow. You don’t have to free up memory manually. 

If we were to compare Flows vs LiveData vs RxJava: 

  • LiveData  is a simple observable data holder. It’s best used to store UI state, such as lists of items. It’s easy to learn and work with. But it doesn’t provide much more than that. 

  • RxJava  is a very powerful tool for reactive streams. It has many features and a plethora of transformation operators. But it has a steep learning curve! 

  • Flow  falls somewhere in between LiveData and RxJava. It’s very powerful but also very easy to use! The Flow API even looks a lot like RxJava! 

 

Flow Operators 

Like RxJava you can do different operations such as map, filter, etc. 

Picture2png.png
Picture3.png

 Here, you used the Flow of names from earlier and you applied two intermediate operators to it: 

  • Map transforms each value to another value. Here, you transformed name values to their length. 

  • Filter selects values that meet a condition. Here you chose values that are less than five. 

Picture4.png

 

Flow will emit values one at a time. You then apply each operator to each of the values, once again, one at a time. And finally, when you start consuming values, you'll receive them in the same order.  You'll notice that nothing happens! This is because intermediate operators are cold. When you invoke an intermediate operation on a Flow, the operation is not executed immediately. Instead, you return the transformed Flow, which is still cold. The operations execute only when you invoke a terminal operator on the final stream. 

 

Terminal Operators 

Because Flows are cold, they won't produce values until a terminal operator is called. Terminal operators are suspending functions that start the  collection  of the flow. When you invoke a terminal operator, you invoke all the intermediate operators along with it.

Picture5.png