Concurrency with Kotlin Flow

Jun 5 2024 · Kotlin 1.9.20, Android 14, Android Studio Iguana

Lesson 04: Advanced Flow Management

Hot Streams Demo

Episode complete

Play next episode

Next
Transcript

In this demo, you’ll see an example of a hot flow. Start Android Studio and open the 04-advanced-flow-management/Starter folder. As mentioned in previous lessons, make sure to use the starter project and not the project you had from the previous lessons, because we have added some helper functions.

In the previous lesson, you learned about cold and hot streams. Maybe you noticed, but you’ve already been working with hot streams. In your ViewModels, you used MutableStateFlow to emit states to your views. Every time you use MutableStateFlow, you’re working with a hot stream. And if you now take a closer look at MovieRepository, you’ll notice a few examples of cold streams — like fetchFavoriteCategories() and fetchMoviesByCategory().

Now, open MovieRepository.kt. When you have a database in your app, it usually emits data as a hot stream. To be precise, it emits the current value when you subscribe to it; it also usually has a mechanism to notify you when the data changes.

Add the following functions:

fun moviesByCategories(): Flow<Map<String, List<Movie>>> = movieDatabase.getMoviesByCategoryFlow()

suspend fun updateMoviesByCategories(category: String) {
  val moviesForCategory = moviesByCategoryDummyData[category]
  val shuffledMovies = moviesForCategory!!.shuffled()
  movieDatabase.updateMoviesByCategory(category = category, movies = shuffledMovies)
}

moviesByCategories() returns a hot stream of movies by category. updateMoviesByCategories() is a suspending function that updates the movies for a given category in the database. In this case, it only shuffles the movies for the category, but in a real app, you’d probably fetch new data from a server.

Next, open HomeViewModel.kt. You’ll update fetchMoviesByCategories() to use the new hot stream.

private fun fetchMoviesByCategories() {
  viewModelScope.launch {
    movieRepository.moviesByCategories() // HERE
      .transform { moviesByCategories -> 
        //...
      }
      .collect {
        _moviesByCategories.emit(it)
      }
  }   
}

You replaced the fetchMoviesByCategory() call with moviesByCategories(). This change makes the ViewModel listen to the hot stream of movies by category.

Next, in the same ViewModel, update refreshCategory() like this:

fun refreshCategory(category: String) {
  viewModelScope.launch {
    movieRepository.updateMoviesByCategories(category)
  }
}

This function calls updateMoviesByCategories() in the repository to update the movies for a given category.

Excellent! Run the app now. You’ll see that the movies are shuffled every time you click the Refresh button.

That ends this demo. Continue with the next lesson, where you’ll learn more about filtering operators.

See forum comments
Cinema mode Download course materials from Github
Previous: Cold & Hot Streams in Kotlin Flow Next: Handling Errors in Kotlin Flow