Android MVVM Architecture with Kotlin Coroutine

Rifqi M Fahmi
4 min readJul 30, 2019

Today I found many tutorials online explaining how to implement MVVM architecture in your Android Studio project. This took me back in 2018 when I start to learn MVVM, Coroutine, unit test, UI test, TDD, and the new Android Jetpack architecture. I then group the resources I have learned to create a single sample app which you can find on GitHub. I realize that some people have an interest in the sample I created by seeing the star increasing about +4 / month on average. I know it’s not a lot and I thought it would be nice to give detailed information about the app which I will write in this post.

About The App

There are some pieces of information you need to know about this simple Android app project that I created. When I create this project, my purpose is to follow the google guide architecture. I know there are some files or classes that I haven’t been tested yet, but I plan to implement the test soon. This is what the architecture looks like:

google android guide architecture

In this project, I didn’t use Dependency Injection like Dagger, Koin, etc for simplicity. I also didn’t use all the Android Jetpack Architecture components, only use Room, ViewModel, LiveData to be precise. Also, there is a typo in package name ../foorbalapps/.. when it’s supposed to be ../footbalapps/.. and I just realized that after long commits ahead 😕.

app preview

The MVVM

Take a look at the ViewModelFactory.kt file that I create:

I create a class that extends the ViewModelProvider.NewInstanceFactory class to provide me the ViewModel instances. Why do you need to create you own factory? can’t you just call the VeiwModelProviders.of(this)[MyViewModel::class.java]? No, because I need several dependencies for my ViewModel class, context and repository. Keep in mind that you need to pass the application context to the ViewModel to avoid memory leak as the documentation said in this page. Notice that I use AndroidViewModel instead of ViewModel class.

The LiveData

Inside the ViewModel I create some LiveData field that the view can observe to. There are some data that wrapped inside Resource class. Why? This is helpful to determine the current status of the data when getting it. You can see the available status at Resource.kt file.

As you can see I use the enum class for the data status. I know many of you might argue that enum is really slow. But I remember in a Youtube video which I forgot the name (sorry 😕) when Chat Haase and Romain Guy talk about it. They said that nowadays you don't have to worry using enum because of the ART (Android Runtime) solve that slow problem that happened when using Dalvik. If you guys find the video I men leave it in the comment, and I will add it to this post :).

The repository is responsible to supply the LiveData variable with a value so that the views can observe the changes and react appropriately to it.

The Room

As the doc said, Room is a persistence library that provides an abstraction layer over SQLite to allow for more robust database access while harnessing the full power of SQLite. Here are several winning points of Room that make me use it:

  • Has SQL syntax compile-time checking. when you make a typo or some mistake in your query string, the compiler will notify you and throw an error. It’s nice so that it doesn’t happen at runtime that caused the app to crash.
  • It has LiveData support 👍.

The Coroutine

When I build this app, coroutine had just newly announced its production-ready coroutine. There are a few resources that I can find, many resources that I found still using the experimental one. Fortunately, I am able to implement it and as well as unit test it. If you take a look at the NetworkBoundResource.kt file:

The NetworkBoundResource class need ContextProviders class as its dependency:

The ContextProviders class contains 2 fields of CoroutinContext Main and IO. The dispatchers Main is for running the task on the UI thread, while the IO is on the background. Why you need to create a class for that? can you just pass the Dispatchers.Main or Dispatchers.IO to the coroutine builder? Yes, that would be possible, but by doing that you can not unit test the code because you need to pass the Dispatchers.Unconfined to the coroutine builder so that the code run synchronously.

The Unit and UI Test

Not all classes have been tested. There are several classes that have been covered by the test which you can see in the test package. For Unit Test I use Mockito to mock object. Since the Mockito version that I used in this project can’t stub Kotlin classes and functions which are final by default, I need to use the kotlin-allopen that open the class when compiling in debug mode. If you try to mock the object without opening it, the test will throw an error.

For UI Test I use espresso which you can read more in the doc.

Improvement

I know this is not the perfect sample app. There are much other good technologies and principles that haven’t been used in this project. One of the concepts that I want to implement is modularization, where you split your single app module to several modules features and libraries thus making it reusable, independent, and faster build (incremental build). If you have any idea or questions you can leave a comment below or create/develop your own improvement by forking the project on GitHub. Thank you

--

--