Android ❤️ MVVM

Ezra Lazuardy
5 min readJul 22, 2020

How to guide about implementing Android MVVM architectural pattern.

Photo by Mark Boss on Unsplash

For mobile apps developer who specialize in native Android, it’s commonplace that when we build a complex apps, we need to manage a lot of code and logic for it. For features such as retrieving data from remote or local database, performing asynchronous task, etc. it will require some implementation in our view (activity or fragment). In the worst case, it can cause code duplication and spaghetti code.

We also have to write the boilerplate code that needed when implementing features. Handling state when device orientation changed is important thing to do too, since we won’t our activity state destroyed when user change it’s device orientation.

Therefore, we need a solution that can simplify our problem below. A simple solution that don’t need much configuration for our apps project.

And the answer for that is something that called architectural pattern. In simple word, architecture pattern is a rule of how we build & structuring apps in general / abstract way.

An architectural pattern is a general, reusable solution to a commonly occurring problem in software architecture within a given context. Architectural patterns are similar to software design patterns but have a broader scope.

I’ve write detailed article explaining architectural pattern here:

The MVVM Architecture

There are many type of architectural pattern implementation out there. And I will explain one of it that recommended by Google for implementing in Android platform. It’s the Model — View — View Model architectural pattern. People usually call it MVVM or MVB (Model — View — Binder) pattern.

Source: Wikipedia

MVVM allow us to create a responsive and dynamic code implementation in Android. It can separates the business logic from your view too, respecting the Single Responsibility Principle that stated in Uncle Martin’s SOLID principle.

This architectural pattern have 3 main component:

View

View is responsible for displaying UI (User Interface) and giving an UX (User Experience) for user. This component will interact with the View Model component to request, send, and save data or state.

View Model

It‘s the most important component in MVVM architecture pattern. View Model is responsible for providing data / state (that hold by Model) to the View component. Not only that, View Model will have to handle all request that needed in View. We can also apply a technique called Data Binding that act like connecting the View to Model class and synchronizes them, so that View can automatically get updated when the Model have changed it’s data or state.

Model

Model is responsible for implementing business logic and hold data or state in your app.

How we apply it to Android?

To implement MVVM architecture in our Android app, we need to use some library provided by Google called Android Jetpack lifecycle library.

Apply this code to your Gradle module.

// Lifecycle Extensions
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"

After that, we can start implement MVVM by creating the Model first. For the sake of this tutorial, I will create a simple Model class that hold a single parameter.

data class User (
val name: String
)

Now, let’s create the View Model using Android Jetpack lifecycle library.

class MainViewModel : ViewModel() {    val user = liveData {
emit(User(name = "Ezra Lazuardy"))
}
}

MainViewModel needs to extend the ViewModel class provided by Android Jetpack lifecycle library so that we can use this class as a View Model in our View.

In the user variable, we assign it with the value of liveData scope. This scope is also provided by Android Jetpack lifecycle library that used to return a Live Data object that can be observed in View. The value of Live Data is determined by the emit() method that we call inside the scope.

For you who don’t know what Live Data is, it’s basically an object that can only be observed to get the value. So instead we directly return a Model using a method or directly save the Model inside a variable and access it from view, View Model will define the Live Data, and the View will observe it.

Maybe you wondering, why we need to do this?. Long story short, the act of observing Live Data allows the View to asynchronously retrieve the value from View Model. This kind of pattern is so helpful when you need to do an asynchronous process such as retrieving data from network or doing some disk read / write. With the help of Kotlin Coroutine inside your View Model, all kind of asynchronous process is applicable.

This is the main reason why I tell you that MVVM can make your apps responsive and powerful in term of logic 😄.

And the last but not least, we will use the View Model from the View (activity or fragment).

class MainActivity : AppCompatActivity() {    // use the View Model    
private val mainViewModel: MainViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// observe the Live Data in View Model
mainViewModel.user.observe(this, Observer { user ->
// set the Text View's text
text_view.text = user.name
})
}
}

The by viewModels() method is used to get the View Model instance with help of the Android Jetpack lifecycle library. And the last thing we need to do is to use the observe() method to observe the data change inside View Model. If the View Model is has prepared the User Model, it will return the value inside the defined Observer, so that we can use it to set the Text View’s text in View (MainActivity).

FYI, View Model has it’s own lifecycle that binded to activity that uses it. This will make data or state inside your View Model will not be destroyed as long as your activity is still not destroyed too. You will notice that the Text View’s text value will remain the same even your device doing an orientation change.

Normally, when Android detect an orientation change, it’ll destroy and recreate the current active View (activity or fragment). You need to save your current data to savedInstanceState bundle if your data are saved inside your activity, so that you can retrieve your data after an orientation change and set the Text View’s text again. But since our data (Model) is saved in View Model, we don’t need to handle it.

Say good bye to savedInstanceState 🤣.

Conclusion

Using a simple approach with MVVM architecture pattern will help you implement a better, powerful, and responsive Android apps. If you look closely, the main key of this architecture is the usage of Live Data inside View Model though.

And as you can see, now the View has no business logic. Each component has it’s own responsibility.

For those who have experienced using Kotlin Coroutines, RxJava, RxKotlin, or RxAndroid, you can apply those asynchronous approach inside View Model, and your View still can retrieve the value asynchronously by observing it first.

--

--

Ezra Lazuardy

“An idiot admires complexity. A genius admires simplicity.” — Terry A Davis