Android Architecture Components With Kotlin - Lifecycle

Google recently released its official guide to the Android app architecture with a bunch of libraries called Architecture Components. This looks very promising since Android has been missing a standard way of implementing some kind of clean architecture. There were many unofficial ways to implement MVP and MVVM patterns, from which I had a chance to use a couple, including Mosby.

The problem was lack of standards. When I switched a project I had to learn completely new MVP/MVC/MVVM implementation which did exactly the same thing I was used to, just in a different way. I always thought it would be nice if Google provided some “official” support for app architecture which the industry could adopt.

In this post, I’m going to explore the ViewModel, LifecycleOwner, and LiveData from the Architecture Components Library. All the code here is of course Kotlin.

The code for this tutorial is available here. The sample app requires Android Studio 3.0, at the time of writing this post I used Android Studio 3.0 Canary 5. If you want to use Canary version of Android Studio along your stable version on the same machine, check out this video. I will update the GitHub repository to more stable versions of Android Studio 3.0 when available.

As an example, I created a simple app which contains Activity and two Fragments. The app is showing two Fragments connected to shared Activity. The first Fragment is displaying simple countdown timer, the second Fragment has all the controls:

Architecture sample app first screenshot

When you tap “START” the app starts the counter:

Architecture sample app second screenshot

The state of the counter is preserved during orientation change, when the shared Activity is being recreated:

Architecture sample app third screenshot

You can also stop the timer or log the timer state.

App’s architecture explained

First, we need to import the required library. To do this we add the dependency to the apps build.gradle file in dependencies section:

// Android Architecture Components

compile "android.arch.lifecycle:extensions:$arch_version"

where '$arch_version' is the library’s version. Google is currently providing Architecture Components as a separate library but after reaching v1.0 it will be part of the support libraries.

Our shared Activity extends LifecycleActivity() from the library.

Our app’s business logic is located in SharedViewModel class, which extends ViewModel class. Its purpose is to “store and manage UI-related data so that the data survives configuration changes such as screen rotations”. The business logic here is a simple countdown timer. We store the formatted time String as MutableLiveData, an Architecture Components holder which stores data that can be observed. The difference between LiveData is that it exposes setters. Note that we also use a TimerStateModel object (custom Kotlin Data class) which also survives orientation change:

In FirstFragment we make the formattedTime observed. First we create timeObserver which updates our tvTimer TextView every time the mFormattedTime in our SharedViewModel is getting changed. We are obtaining instance of our SharedViewModel (see code line 10 below) and then we subscribe to the observer (code line 13). The activity cast as LifecycleOwner which we pass to the observe method is Kotlin’s convenience method to get our SharedActivity instance. We are accessing formattedTime via our public getter.

In the SecondFragment in onViewCreated method first we obtain an instance of our SharedViewModel and then we set all the appropriate onClickListeners (code lines 7-9).

In this simple example we delegated all of the business logic to a ViewModel. Our fragments are only responsible for observing the data changes (using convenience of LiveData) and responding for user input. Everything is managed by the Architecture Components library so there is very little boilerplate. Also, it reduces the possibility of shooting ourselves in the foot by mismanaging app state, which in my experience is one of the most common bugs every Android developer experiences.

If you want to do some further reading about Architecture Components I recommend those excellent articles:

Exploring the new Android Architecture Components library by Joe Birch


Styling Android articles