Android Architecture Components With Kotlin - Lifecycle17 Jul 2017
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.
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:
When you tap “START” the app starts the counter:
The state of the counter is preserved during orientation change, when the shared Activity is being recreated:
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:
'$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: