MVVM in Android

MVVM stands for Model-View-ViewModel, which is a pattern widely adopted in Microsoft WPF and Silverlight. In this article, I am going to discuss the implementation of MVVM pattern in Android (Java) with the help of Android-Binding framework.

MVVM Redefined for Android

Model: Model in Android can be data coming from within your application (including Shared Preferences), Database (in Cursor, or via other Data Access Object) or externally (via Cursor to other Data Contract).

View: All the elements displayed in GUI, that include android.widget.* family, and your custom views.

ViewModel: ViewModel exposes properties and commands for the View, it also serves in data binding between the View and the Model. In Android, most of this job is done in Activity.

Implementation

We use a simple calculator as an example. As shown in the following figure, the calculator consists of some buttons for input and operations, and a text box to display the result.

Once we have the ViewModel ready, we need to bind the ViewModel with the View, and here we are using Android-Binding. Android-Binding can help decouple the View with ViewModel, via XML markup of binding syntaxes, all we need to do is include the library, and add an extra namespace in XML markup for Android-Binding to recognize:

In order to make the ViewModel properties change-aware by the View, we have two ways in Android-Binding to expose them:

Observable-Command pattern: All properties that the View can bind is wrapped in Observable<T>; while commands implements the Command Interface. This is the primary supported method in Android-Binding

POJO: The ViewModel defines Java-styled getter-setter properties, and the ViewModel implements PojoViewModel interface. This is a plugin interface for Android-Binding, and the plugin will convert the ViewModel to Observable-based object. Here, our example will be in Observable-Command pattern. (POJO version is also available in the source code.)

Observable<T>

<T> is any Object, while Observable<T> means a property of type T is Observable, whenever changes are made on it, it will notify its subscribers.

So, we have to wrap the above mentioned properties in Observables:

Observable<Double> Result = new Observable<Double>(Double.class, 0d);

Command

Command is similar to public methods of a ViewModel, they can be invoked by UI widgets.

Binding View with ViewModel

Once we implemented the ViewModel, and declared our layout, we need to bind the ViewModel to the View. With a little effort, the binding is done automatically for you with Android-Binding. In the Activity:

DependentObservable/Converter

Sometimes, we want to format the data, before we present it. For example, we do the calculations using ‘double’ in the calculator, but we don’t want to display the raw double value to user -- the answer can be too verbose for practical usage (like more than 15 significant figure), we want to constrain it to within 10 significant figures.

Of course, we can comb the display value in our ViewModel, before sending it to the View; we do this by using DependentObservable/Converter.

DependentObservable is an Observable that `Observes` other observables, once any of those observables changes, it calculate its value accordingly; a Converter is the same as DependentObservable, only DependentObservable is readonly, a Converter can do reverse conversion.

Since our displayed number in purely for display purposes, we need only DependentObservable. We can explicitly declare the dependentObservable in our ViewModel, but, I would argue that formatting how the view looks like should not be the job of ViewModel, rather, it should be done by View itself.

Android-Binding supports custom Converters (along with some built-in) to declared in XML layout, first, we have to create a class extends from DependentObservable:

Advantages of Using MVVM

Just like any other MVVM platform, using MVVM in Android is good for decoupling back end codes from UIs; in the above calculator example, we can plug a different layout to it, without changing anything in the ViewModel (different way to format the display for example).

Another very big advantage of using MVVM, is you can easily do unit test on your ViewModel. You don’t need to really ‘click’ the button to see if the calculation is correct, but just unit-test your ViewModel’s respective Command.

With Android-Binding framework, it generally results in much cleaner code. Imagine implementing the event-handler for those 15 buttons in traditional event model, it will end up keeping 15 references to the widget, registering ‘setOnClickListener()’ 15 times, and a massive switch-case-default block for 15 branches of event handling. But with MVVM, the Command interface can describe the purpose of them much clearer.

Final Words

I tried to build a few Android MVVM applications, and found out that sometimes the role between ViewModel and Activity can be quite blurry. Since many places in Android Application requires the Context to be used (like getting res, cursor, calling out other activities), it ends up that the ViewModel needed to pass the calling Activity to it, or nested the ViewModel in the Activity class, or even Activity class is the ViewModel as well (it’s ok for very simple ViewModel). Such an approach makes ViewModel working quite parallel with Activity: Activity decided the creation of ViewModel and which View is going to render, also manages the life cycle of ViewModel; ViewModel uses Activity to dispatch requests to the outside world.