Kotlin Flows: The Graduated Coroutine - I

To start with, if you know Reactive programming, you can certainly relate this with Kotlin Flow. But, but, but, let’s start from the start.

What is Reactive Programming?

In very simple words, if you want your code to react to the changes in the data, reactive programming is the way that can rescue your problem statement. To not overcomplicate, I will pause here and read that again.

And that’s it.

Right.

Flow

In coroutines, a flow is a type that can emit multiple values sequentially, as opposed to suspend functions that return only a single value. For example, you can use a flow to receive live updates from a database.

Flow in Kotlin is something that helps us handle a stream of data asynchronously, that executes sequentially.

Let’s break that statement!

So, Flow is a Kotlin language feature that serves as a reactive programming framework and helps your code get notified for the changes. It can further be understood as an extended Coroutine that is dedicated to notify the changes in your code and can emit multiple values at its own will (obviously, as coded) at any given time.

Let’s think of a situation where you need to return multiple values, well that is not even possible using functions. So, Flow is bringing in some new capabilities for the coders that can emit (instead of return) multiple values. And then there can be numerous observers that can collect those values.

Done and dusted!

Really? Nopes, but that’s enough of theory. Let’s jump into an example to understand the Flow’s flow.

Let's get started.gif

Coding arena

Well, enough of info provided to understand the base of Flow. Now, we are going to setup our app to get Flow up and running.

To start with, include following in app’s build.gradle

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'

So, we are going to setup an app, that flashes the latest news whenever it fetches one. For the simplicity of the app, we won’t be fetching the news in real, but will be simulating it using a list that emits the news after every second. This will be a very basic yet enough to let you know about how emit works for a flow.

Let’s setup a LatestNewsViewModel, as follows:

class LatestNewsViewModel: ViewModel() {

    private val newsList = listOf<String>("World welcomes new year 2022 with high hopes, Happy New Year 2022 to all.", "WHO warns countries worldwide", "Elections on stake, who will win?", "The rise of IT raids", "End of example news")
    private val refreshInterval = 1000L

    val latestNews: Flow<String> = flow {
        for (s in newsList) {
            emit(s)
            delay(refreshInterval)
        }
    }
}

This ViewModel setup is kept as simple as it could be. It contains a

  • newsList that contains few news from around the world.
  • refreshInterval that refers to the interval after which each news will be emitted.
  • latestNews that is a Flow which allows the news (as a String) to be emitted after every second.

In the MainActivity, which in this example, is built with Jetpack Compose. Let’s see, how we are going to set it up. Inside the onCreate() of the Activity, set the content as follows:

setContent {
            LetsFlowTheme {
                val newsViewModel = viewModel<LatestNewsViewModel>()
                val news = newsViewModel.latestNews.collectAsState("Happy New Year 2022")
                Surface(color = MaterialTheme.colors.surface) {
                    FlashNews(news)
                }
            }
        }

Even this is setup pretty straight forward, just to keep it simple to understand. It contains a

  • newsViewModel that holds a reference to the LatestNewsViewModel.
  • news that holds the State and is responsible for collecting the emitted News from the latestNews flow.
  • Then we have setup a Surface that includes FlashNews (Custom composable). The FlashNews composable can be achieved as follows:
@Composable
fun FlashNews(news: State<String>) {
    Text(
        text = news.value,
        fontSize = 24.sp,
        modifier = Modifier
            .fillMaxSize()
            .wrapContentWidth()
            .wrapContentHeight()
            .padding(8.dp),
        textAlign = TextAlign.Center
    )
}

This surely is an ugly composable, but that’s not what we want to achieve as part of this article. We will have a look at it later somewhere.

Well, that’s it.

weird_dance.gif

We will further explore Kotlin Flows in-depth, in the coming articles of this series. Till then, take care.

The code can also be found on Github: https://github.com/AbhasVohra/Flow_FlashNews