Kotlin Flow for Android: Getting Started
In this tutorial, you’ll learn about the basics of Kotlin Flow, and you’ll build an Android app that fetches weather forecast data using Flow. By Dean Djermanović.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Kotlin Flow for Android: Getting Started
30 mins
Searching Locations
So far, your app displayed a forecast for a hardcoded location. Now you'll implement the search functionality! This will allow users to search for a specific location using coroutines and Flow. As the user types in the search box, the app will perform a search for every letter typed and will update the search result.
In HomeActivity.kt, you already have a listener attached to the search view. When the user changes query text, the app sends the new value to queryChannel
in HomeViewModel.kt. HomeViewModel.kt uses a BroadcastChannel
as a bridge to pass the text from the view to the ViewModel. offer()
passes the text and synchronously adds the specified element to the channel.
Querying Locations
Now add the logic for consuming the events from the channel as a Flow
:
private val _locations = queryChannel
//1
.asFlow()
//2
.debounce(SEARCH_DELAY_MILLIS)
//3
.mapLatest {
if (it.length >= MIN_QUERY_LENGTH) {
getLocations(it)
} else {
emptyList()
}
}
//4
.catch {
// Log Error
}
Here's what happens in this block of code:
- First, the call to
asFlow
converts theChannel
into aFlow
. - Next,
debounce()
waits for values to stop arriving for a given time period. This is used to avoid processing every single letter typed by users. Users usually type several letters in a row. You don't need to make a network request until the user stops typing. This ensures that you're performing the API call only after 500 milliseconds have passed with no typing! - Then,
mapLatest()
performs the API call and returns location results. If the original flow emits a new value while the previous API call is still in progress,mapLatest()
ensures that computation of the previous block is canceled.mapLatest()
performs the API call only if the search query contains at least two characters. - Finally,
catch()
handles errors.
Add locations
to HomeViewModel.kt. This allows you to observe from the activity:
val locations = _locations.asLiveData()
Here you're using asLiveData()
to collect values from the origin flow and add transform them to a LiveData
instance.
Open HomeActivity.kt and delete the call from onCreate()
to homeViewModel.fetchLocationDetails()
. Instead observe locations
from initObservers()
:
private fun initObservers() {
homeViewModel.locations.observe(this, Observer {
locationAdapter.setData(it)
})
...
}
Once again, build and run the app. Now enter a search query. You'll see the options generated from your query:
Go ahead and tap any of the options. The home screen will display forecast data for a newly selected location.
Why Kotlin Flow
There are already other implementations of the reactive stream specification, such as RxJava. So why use Kotlin Flow? One reason is that you can't use JVM-specific libraries like RxJava in Kotlin multi-platform projects. But Flow is part of the Kotlin language, so it's ideal to use in Kotlin multi-platform projects.
Also, Kotlin Flow has fewer operators, but they are much simpler. A single operator can handle both synchronous and asynchronous logic since the block of code that operators accept can be suspended!
And Kotlin Flow is interoperable with other reactive streams and coroutines. Since it's built on top of coroutines, it provides all the perks of structured concurrency and cancellation. In combination with suspending functions, it produces a simple, readable, and understandable API. It also supports backpressure out of the box.
Where To Go From Here?
You can download the final project using the Download Materials button at the top or bottom of this tutorial.
You've created an app that uses Kotlin Flow for communication between application layers. In the process, you learned what is so special about Kotlin Flow and how it's different from existing solutions. You also used Flow builders to create a Flow. You became familiar with basic operators to transform a stream of data. And finally, you applied terminal operators to consume the values!
To gain more in-depth knowledge about Kotlin Flow, check out our Kotlin Flow: Getting Started video course. You'll learn a lot more about Flow builders, operators, and cancellation. You'll also learn how to work with Flows, change its context, add buffers, combine multiple Flows, and handle exceptions!
We hope you've enjoyed this tutorial! If you have any questions or comments to share, please join the forum discussion below. :]