
Using LiveData & Flow in MVVM — Part I
Lately, I have been searching for the best practices of Kotlin Flow in MVVM architecture. After I have answered this question about LiveData and Flow, I’ve decided to write this post. In this post, I will be explaining how to use Flow with LiveData in the MVVM pattern. Then we will see how to change the app theme by using Flow.
You can access the sample project from here:
Disclaimer: This post assumes that you are already familiar with Flow. If you are not, I suggest you check docs and this article by Roman Elizarov.
What is Flow?
Flow is a reactive stream in the coroutines library which is able to return multiple values from a suspend function [1].
Even though the use case of Flow seems very similar to LiveData, it has more advantages like:
- Asynchronous by itself with structured concurrency [2]
- Simple to transform data with operators like map, filter …
- Easy to test
How to use Flow in MVVM
If your app has MVVM architecture, you normally have a data layer (repository, data source, etc.), ViewModel and view (Fragment or Activity). You would probably be using LiveData for data transfers and transformations between these layers. But what is the main purpose of LiveData? Is it designed to make data transformation?
LiveData was never designed as a fully fledged reactive stream builder .
says Jose Alcérreca in Android Dev Summit 2019. Since LiveData is a lifecycle aware component, it is best to use it in view and ViewModel layer. But how about the data layer? I think the biggest problem of using LiveData in the repository level is all data transformation will be done on the main thread unless you start a coroutine and do the work inside. This is why you might prefer suspend functions in the data layer.
Let’s say you want to fetch weather forecast data from the network. Then it will be similar as below with suspend function in your repository.
You can call this function with viewModelScope in ViewModel.
This approach works fine with one-shot requests which are run each time when they are called [3]. But how about when fetching data streams?
Here is where Flow comes into play. If you want to fetch real-time updates from your server, you can do this with Flow without any concern of leaking resources since structured concurrency forces you to do so.
Let’s convert our repository so that it returns Flow.
Now, we are able to return multiple values from a suspend function. You can use asLiveData extension function to convert Flow to LiveData in ViewModel.
This looks pretty much the same as using LiveData since there is no data transformation. Let’s see fetching real-time updates from the repository.
When you are fetching real-time weather forecast data, all data transformation inside map function will be done asynchronously with the scope in which Flow is collected.
Note: You can achieve the same functionality for data transformation by using liveData builder if you are not using Flow in the repository.
To get back to real-time data fetch with Flow again, we can see that it is not blocking the UI by updating the text field while observing the data stream.
Then it will look like:

Changing the theme of your app with Flow 🌈
Since Flow can emit real-time updates, we can think of user input as an update and send it through Flow. In order to do that, let’s create a theme data source that has a theme channel for broadcasting updates.
As you see, there is no direct access to themeChannel
from outside. themeChannel
is converted to Flow before it is sent.
It is better to consume theme updates in activity level since all updates from other fragments can be safely observed.
Let’s fetch the theme updates in ViewModel:
And it can easily be observed in the activity:
The only thing left is to push the button in the fragment ⏯
Voilà! Just changed the theme with Flow 🔥

What’s next
In this post, we have seen how to use Flow for repository and LiveData for ViewModel in MVVM architecture. Also, we changed the app theme using Flow & LiveData.
In the next post, I will be explaining about using only Flow in all layers. Stay tuned!