Simplifying the Android developer’s life with Architecture Components

Some weeks ago at the I/O 2017 Google announced that they are working on some components to make the Android developers‘ life easier. They released a bunch of libraries which are supposed to take care of the lifecycle and suggest an architecture to rely on when developing an app. Despite the libraries not being considered stable by now, the community has been pretty excited about this and is adapting to it already. And indeed the libraries are working pretty stable already, some APIs might change though due to community feedback. Let’s have a closer look!

So what’s so interesting about these components to raise that much attention? The answer is pretty obvious once you know the initial idea. The team behind the project talks about this in the Android Developer Backstage Podcast (Episode 72: Architecture Components 1 – Lifecycle). They started interviewing developers about their major pain points developing for Android. It became pretty clear that it’s always the same issues people are struggling with for years. Amongst them the complicated lifecycle, a missing unified architecture and a simple persistence layer to keep the UI in sync with data updates during configuration changes.

Architecture

For a long time Google avoided to make a statement about a preferred architecture and basically went with the idea „Do whatever you want“. As a result people ended up using a lot of different patterns to write apps over the last few years. Some popular ones are MVC, MVP, MVI, Redux or MVVM to name just a few of them. Each of them is fitting the Android environment more or less and has its pros and cons.

Now, with their new libraries, Google is finally suggesting a unified architecture. They designed it based on their idea how apps should be developed.

What Google is proposing is pretty close to the MVVM model which became pretty popular. The idea is that every view, which can be an activity or fragment for example, has a corresponding ViewModel. The model takes care of all the „hard work“ like processing user input, updating data and so on.

There is a class called ViewModel in the libraries which can be extended to implement the pattern. It has quite some nice features: An instantiated object survives configuration changes for example and you get pretty unit-testable code. Depending on the complexity of the project there can be another layer, the DataModel. It takes care of providing all the data. Most of the time there is more than one data source. For example a web service providing data which are stored in a database for later usage.

The DataModel decides where the requested information should be taken from and provides it to the ViewModel.

LiveData

Using the ViewModel pattern you quickly reach the point where you start thinking about the best way to communicate between the view and the model. Especially in the early days of Android development it had been a problem to know when to update the view. There were for example app crashes because an async task had only finished when the app was already in the background and the view was destroyed.

Since then there have been a lot of different solutions for this problem (RxJava to the rescue!). With the architecture components Google is working on something called LiveData to fix this once and for all. It’s a data holder class which allows a consumer to observe the data every time the object is updated. Furthermore LiveData respects the lifecycle. This means the LiveData object will only update the View as long as it is in an active state (STARTED or RESUMED). This state is updated every time a lifecycle event happens.

Using it is fairly simple. Let’s assume we have a view which shows a list of jokes and the view model providing a list with data; it looks like this:

Having this we can register the view to updates from the ViewModel:

And that’s it. Now every time some method calls jokeLiveData.setValue the view will be updated if it is still active. As mentioned before there is another advantage provided by the ViewModel. It survives configuration changes. So when the device is rotated and goes through the lifecycle, the state is kept and the screen will get the data once it is rebuilt. But be careful, there’s one thing to take into account: The model does not survive activity recreation. So when the activity gets destroyed by the system while your app is in the background, the data is lost. You’ll have to come up with a solution to save and restore the state in onSaveInstanceState/onRestoreInstanceState. The data itself is ideally persisted in a database anyways. There already are plenty of frameworks to deal with persistence like Realm or GreenDao for example. Google just introduced a solution called Room which is shipped with the architecture components as well.

Room

Room is a persistence library providing an abstraction layer over SQLite. The usage is quite simple. Going back to the Jokes example an entity looks like this:

It contains a primary key, which is required and another field containing the joke. To access the data an interface is created and implemented:

Room provides RxJava support and offers Flowable directly as a return value, which is pretty nice. For the last step you need to get an instance of the database which should be a singleton that is shared across the app.

As you can see the usage is pretty straightforward and easy to start with. With the latest version of Android Studio, the queries are already checked during compile time, which allows to show errors already in the IDE. And that’s it, now we have all the tools needed for handling a clean lifecycle, managing configuration changes and persisting the data.

Sum up

Google is providing some very useful components which can make the developers‘ life a lot easier by tackling the biggest pain points in daily Android programming. But that does not mean that every existing app needs to be updated and migrated to use these components. They merely provide one way to solve problems you usually stumble upon while developing an app. If there already is a working solution implemented based on a working architecture, there is no need to change anything about it. In my opinion it is better to have one consistent architecture than several different ones which are applied in different places of the project, as this makes the code harder to understand and difficult to maintain.

To sum up it is definitely worth taking a look at the components. It feels like something that should have been around for years, as it can really speed up development. Despite being in an alpha stage the libraries are pretty stable and also fun to play with. Many developers already started to adopt it which means that sooner or later it can be seen in a lot of apps so it’s better to not miss out on it. They are a good starting point for a new project to create a scalable, testable and structured app while also saving time.

comments powered by Disqus