Simple Android MVVM using RX and Kotlin

Ovidiu Latcu
Corebuild Software
Published in
5 min readAug 8, 2017

--

I guess you all know that for the last year or so, all the hype in Android development is about MVVM and RX. Also, this year Google announced at I/O the new Architecture Components, a set of libraries which help you build a robust, testable app using a MVVM architecture. So, as I was looking for an architecture to an existing small app build using MVC (old style Android, with a lot of business done in the UI/Fragments) and also an architecture for an upcoming project (where we will have both Tablet & Phone UIs) I started evaluating my possibilities.

I won’t spend too much time explaining what MVVM is, there are a lot of great articles and presentations about MVVM. There’s also this great article comparing MVC , MVP and MVVM on Android. So how does MVVM look ?

MVVM Architecture

The View :

  • Activity / Fragment / View
  • Requests relevant UI data from the ViewModel
  • Requests the ViewModel to perform operations on the Data (insert/edit data based on user input )

The ViewModel :

  • Acts as a bridge between the View and the Model
  • Requests/aggregates data from the Model, and transforms it for the View
  • Expose means for the View to update the Model

The Model :

  • Also know as DataModel / Repository
  • Holds the business logic
  • Serves data from various sources (DB, REST Api, cache)

So, why I am getting tired of MVP ?

  • Too many interfaces
  • Presenter is coupled to the View
  • Usually a change in the View implies changes in the Presenter (and also, adding new methods on the view & presenter interfaces)
  • Can’t really reuse the Presenter as it is usually coupled to a specific view

What’s better in MVVM ?

  • No more dozens interfaces
  • ViewModel and DataModel still testable using JUnit
  • ViewModel no longer coupled to a specific View
  • ViewModels can supposedly be used and/or composed in multiple views (imagine a completely different tablet View that reuses multiple ViewModels that have been used so far independently on some phone Views)

Why not using the Android Architecture Components ? Is there something wrong with them ?

  • Not necessarily, but I’m being cautious after previous experiences with Google libraries / APIs (Volley, Fragments, Loaders, AsyncTasks)
  • At the time of my writing, they are still in alpha, so things might still change and might not be stable
  • I feel they require too much code to write in some cases (maybe because I am used with Kotlin and the samples use Java)
  • The libraries are not open source
  • I want to keep my architecture clean, as simple as possible, be in control of it and understand what’s happening under the hood (just look at the ViewModelProviders.class of the library; dig down in the source code, and you’ll see Fragments are used to retain ViewModels; things look error prone and I’d rather build & inject my ViewModels using RX & Dagger and keep everything as simple as I can - KISS principle)
  • I know the Architecture Components are Lifecycle aware and this can be of great help, but I don’ need those features in my case, and I can easily deal with lifecycle (this might not be the case for you and your apps)
  • I know LiveData can easily push data updates to multiple observers (which is again really helpful) but I feel this can also easily be achieved using a RX PublishSubject

As an example, I am going to use a simple app, that retrieves a list of users from the API, and displays it.

Below you can see how we can implement a simple UserRepository that fetches data from the API and sends it to ViewModel which will prepare it for the View.

UserListViewModel : the ViewModel, talks to the Repository to get the data and prepare it for the view

UserRepository : the Repository /DataModel / Model , gets the data from various sources (cache, DB, API )

UserApi: a simple data source, that takes the users list from the API

We can alter our UserRepository and make it store the retrieved user list from the API, and each time getUsers() gets called we immediately return first the cached users, and after that fresh new data from the API. This is easily achieved with RX’s mergeWith() operator.

(Of course, the UserRepository, UserViewModel will be probably some Singletons, provided by Dagger)

What I also like about this approach (separating the ViewModel from the DataModel/Repository), is that the ViewModel does not know, and does not care where the data comes from. It is also not responsible for caching or storing the data. We were able to introduce caching of the API data without any changes in our ViewModel.

Testing our UserRepository is fairly easy using a TestObserver

Conclusion

This is just my personal view on the current state of MVVM in Android and the new Architecture Components. I recommend you too go and explore the Google Architecture samples, play with RX, and in the end choose what better fits your needs.

Do not choose an architecture or framework because it is pushed / recommended by Google. Do not choose it because everybody talks about it. Do not choose it because it worked greatly for other teams. Choose an architecture that suits your needs, fits well to your team structure, keeps your code clean, helps you easily test your code, and most importantly allows you to easily add new features.

Upcoming

In the following articles I will try to improve the sample and add a DB source for offline access, and also implement something similar to LiveData using RX.

Edit: check my article Android Repository Pattern using Room & RX, too see how we can easily add a database source to our repository.

--

--