Chapters

Hide chapters

Advanced Android App Architecture

First Edition · Android 9 · Kotlin 1.3 · Android Studio 3.2

Before You Begin

Section 0: 3 chapters
Show chapters Hide chapters

10. Model View ViewModel Theory
Written by Aldo Olivares

In this chapter you will learn about a distant relative of MVP — the MVVM Architecture Pattern.

First, you will explore how MVVM works at a high level. You will learn about each of its layers and how they communicate between each other. You will also learn how MVVM improves the testability of your apps by providing a clear level of abstraction to your code.

Finally, you will understand the advantages and limitations of MVVM to know when and how to apply it properly.

Ready? Let’s get started!

The Model-View-ViewModel pattern

MVVM stands for Model-View-ViewModel. MVVM is an architectural pattern whose main purpose is to achieve separation of concerns through a clear distinction between the roles of each of its layers:

  • View displays the UI and informs the other layers about user actions.
  • ViewModel exposes information to the View.
  • Model retrieves information from your datasource and exposes it to the ViewModels.

At first glance, MVVM looks a lot like the MVP and MVC architecture patterns from the last chapters.

The main difference between MVVM and those patterns is that there is a strong emphasis that the ViewModel should not contain any references to Views. The ViewModel only provides information and it is not interested in what consumes it. This makes it easy to create a one-to-many relationship wherein your Views can request information from any ViewModel they need.

Also of note regarding the MVVM architecture pattern is that the ViewModel is also responsible for exposing events that the Views can observe. Those events can be as simple as a new user in your Database or even an update to a whole list of a movie catalog. Now, you will explore how each of the MVVM layers work one by one.

The Model

The Model, better known as DataModel, is in charge of exposing relevant data to your ViewModels in a way that is easy to consume. It should also receive any events from the ViewModel that it needs to create, read, update or delete any necessary data from the backend.

In Android, you usually create Models as Kotlin data classes that represent the information that you obtain from your data source, such as an API or a database. For example, say you have an app that displays information about the latest movies. You would surely create a Movie class that contains data such as the title, description, time and release date of the movie.

When following this architecture pattern, you should strive to stick to the single-responsibility principle of software design, creating a Model for each logical object in your domain. This will make it much easier for you to create the necessary ViewModels later on.

Since the Model implementation does not change much from the previous patterns, you won’t dive deeper into this layer, here. However, if you want to learn more, review the Models section of the MVC architecture pattern chapter.

The ViewModel

The ViewModel retrieves the necessary information from the Model, applies the necessary operations and exposes any relevant data for the Views.

The Android platform is responsible for managing the lifecycle events of the classes that handle the UI, such as activities and fragments. The operating system can destroy or re-create your activities at any time in response to certain user actions or events.

The problem is that, if Android destroys or re-creates an activity or fragment, all data contained within those components is lost. For example, your app may include a list of movies in one of its activities. If the activity is destroyed and re-created, the list of movies will have to be retrieved again. This may slow down your app if the list is housed in an external database or API.

The most common solution to this problem is to save your data in your onSaveInstanceState() bundle and restore it later in your onCreate() method. But this approach only works for primitive data such as Integers or simple classes that can be serialized and deserialized.

Thanks to Google’s new Architecture Components, you now have a special class to build your ViewModels called ViewModel.

The ViewModel class is specially designed to manage and store information in a lifecycle-aware manner. This means that the data stored inside it can survive configuration/lifecycle changes like screen rotations.

The ViewModel remains in memory until the lifecycle object to which it belongs has completely terminated. This behavior applies to activities when they finish and in fragments when they are detached.

In the next illustration, you can see how the ViewModel remains active and retains information through the whole lifecycle of an activity, even when it is destroyed:

Note: You don’t need to use Android’s architecture components to implement your own ViewModels. It is just a component that Google provides to make development easier and reliable.

To communicate changes in the data, ViewModels can expose events that the Views can observe and react accordingly. Those events can be as simple as a new user having been created in the database or an update to an entire movies catalog. This way, ViewModels don’t need to have any reference to Activities, Fragments or Adapters.

You will learn much more about Google’s ViewModel class in the next chapter, so don’t worry if something seems confusing at the moment.

The View

The View is what most of us are already familiar with, and it is the only component that the end user really interacts with. The View is responsible for displaying the interface, and it is usually represented in Android as Activities or Fragments. Its main role in the MVVM pattern is to observe one or more ViewModels to obtain the necessary information it needs and update the UI accordingly.

The View also informs ViewModels about user actions. This makes it easy for the View to communicate to more than one Model. Views can have a reference to one or more ViewModels, but ViewModels can never have any information about the Views.

In Android, you will usually communicate the data between the Views and the ViewModels with Observables, using libraries such as RxJava, LiveData or DataBinding.

You can see how the interaction between each layer works, below:

Note: One little trick that will help you know if your Views and your ViewModels are properly detached is to verify that there is no reference to any com.android.* package in your ViewModels. There are only a few exceptions to this rule, like the Android Architecture Components package: com.android.arch.*

MVVM by example

The next two chapters will cover practical examples of MVVM. You will learn how to rewrite the Movies app with two different approaches: Using architecture components and using Data Binding.

To better understand the theory, let’s dig into a basic example that shows you how you would connect a View to a ViewModel in a TODO list app.

There’s no need to type this code out any where, the code is presented here as an example. Keep reading and we’ll concretely break down the pieces that make MVVM.

class MainViewModel: ViewModel() {

  //1
  private var items: LiveData<List<Item>>? = null
  //2
  fun getItems(): LiveData<List<Item>> {
    if (items == null) {
      return db.itemDao().getAll()
    }
    return items ?: emptyList()
  }
}

class MainActivity: AppCompatActivity() {

  //3
  private lateinit var mainViewModel: MainViewModel

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    //4
    mainViewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)

    //5
    recyclerView.layoutManager = LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)
    val adapter = ItemAdapter()
    recyclerView.adapter = adapter

    //6
    mainViewModel.getItems().observe(this, Observer {
      if (it != null) {
        adapter.list.clear()
        adapter.list.addAll(it)
        adapter.notifyDataSetChanged()
      }
    })
}

Note: The Model code has been omitted for brevity.

Taking each commented section in turn:

  1. The ViewModel declares a property that will contain a LiveData list of items. The LiveData class allows any View to observe for any changes on the list and update the UI.
  2. getItems() is an accessor method that returns the list of TODO items. If the list of items is null, you call the getAll() method of your ItemDao interface to retrieve them from your database.
  3. The View holds a reference to your ViewModel. The ViewModel property is defined as a lateinit var so that the compiler knows it won’t be initialized until after class initialization.
  4. In the onCreate() method, you should initialize every reference to the ViewModels you will need. In this case, to the MainViewModel.
  5. Next, you configure the recycler view layout and provide an adapter.
  6. Finally, you call the observe() method of your LiveData list of Items. If there is any change, you can act accordingly to update the necessary UI elements. In this case, you are updating the list property of the adapter to update your RecyclerView.

As you can see, it’s fairly straightforward to implement your ViewModel along with your Views. Once you master them, you will see how they help to make your code easy to test.

MVVM advantages and concerns

One problem that the MVC architecture patterns have in common is that the Controllers and the Presenters are sometimes very hard to test due to their close relationship with the View layer. By handling all data manipulation to ViewModels, unit testing becomes very easy since they don’t have any reference to the Views.

One problem present in some architectures, MVC in particular, is that the business logic is quite difficult to test due to a lack of separation from the View logic. By confining all data manipulation to the ViewModel, and by keeping it free of any View code, the business logic becomes unit testable, as it can be executed without requiring the Android runtime.

Another problem with the MVC pattern is that there is usually confusion as to which code goes where. Sometimes, when code doesn’t fit in the Model or the View, it is put in the Controller. This often leads to a common problem known as fat controllers, whereby the controller classes become overly large and difficult to maintain.

MVVM solves the fat controller issue by providing a better separation of concerns. Adding ViewModels, whose main purpose is to be completely separated from the Views, reduces the risk of having too much code in the other layers.

MVVM vs. MVC vs. MVP

You might be wondering why you would want to use MVVM over MVC or MVP. After all, MVC and MVP are among the most common Android architecture patterns and are both very easy to understand. There has been endless debate on which approach is best, but the answer largely boils down to personal preference.

As we usually say in the development world, there is no silver bullet to solve every software design issue. And although MVVM is a very useful development pattern, it also has some disadvantages.

The main disadvantage of this architecture pattern is that it can be too complex for applications whose UI is rather simple. Adding as much level of abstraction in such apps can result in boiler plate code that only makes the underlying logic more complicated.

At the end of the day, it is up to each developer to decide which is the best architecture pattern for each development project.

Key points

  • MVVM stands for Model-View-ViewModel.
  • MVVM is an architecture pattern whose main objective is the separation of concerns.
  • Views display the UI and inform about user actions.
  • The ViewModel gets the information from your Data Model, applies the necessary operations and exposes the relevant data to your Views.
  • The ViewModel exposes backend events to the Views so they can react accordingly.
  • The Model, also known as the DataModel, retrieves information from your backend and makes it available to your ViewModels.
  • MVVM facilitates Unit Testing of your code.
  • MVVM may be too complex for applications with simple UI.

Where to go from here?

There are several patterns that you could use to build your Android Apps. The Model-View-ViewModel architecture pattern is just one of the many tools that helps you write clear and concise code. But MVVM combines the advantages of the MVP and MVC architecture patterns with other useful features such as DataBinding. It improves the testability of your code by providing a greater level of abstraction and reducing the amount of boiler plate code in your projects.

In the next chapter, you will apply your knowledge by re-writing the Movies app using MVVM.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.