Android Architecture Components

Android Architecture Components (AAC) is a new collection of libraries that contains the lifecycle-aware components. It can solve problems with configuration changes, supports data persistence, reduces boilerplate code, helps to prevent memory leaks and simplifies async data loading into your UI. I can’t say that it brings absolutely new approaches for solving these issues, but, finally, we have a formal, single and official direction.
AAC provides some abstractions to deal with Android lifecycle:
- LifecycleOwner
- LiveData
- ViewModel

LifecycleOwner is a single method interface that serves to provide an instance of a Lifecycle object. The library already includes a LifecycleActivity that inherits from FragmentActivity and implements LifecycleOwner. It also contains a LifecycleFragment that inherits from Fragment from the support library.

LifecycleRegistry is a default implementation of Lifecycle that we can use for a custom LifecycleOwner.

Please notice, that we have to hold a strong reference to the instance of LifecycleRegistry, otherwise GC will collect it and LifecycleObserver of LiveData won’t see the active observers from LifecycleOwner and our views won’t receive the updates.

You can find the source code of LifecycleRegistry if you want to understand lifecycle management better.
LiveData is a holder for some data and an implementation of the Observable pattern. It lets you detect data changes inside an instance of LiveData similar to RxJava Observable.

The main benefit is the fact that our UI components, like TextView or RecycleView, observe LiveData, which, in turn, observes the lifecycle of an Activity or Fragment, using a LifecycleObserver.

To change the data inside LiveData, we can use the setValue
method from a main thread or postValue
from a background thread. If we call postValue
multiple times before the main thread executed a posted task, only the last value will be dispatched.

Due to the fact that LiveData is an abstract class, the library contains a simple implementation:

If you want to detect changes in another instance of LiveData, you can use MediatorLiveData.

This class correctly propagates its active/inactive states down to the source object.
ViewModel is a view data ownership model that assumes the following responsibilities:
- Automatic retention during configuration changes
- Management of async calls
- Holding data for UI
Thanks to LifecycleOwner, it has a very simple vision of the lifecycle of Activity or Fragment: just initialization and cleaning.

The instance of ViewModel isn’t destroyed during configuration changes. The new Activity gets the pre-existing object of ViewModel, and using a mechanism of LiveData, immediately receives the last data.

This fact makes ViewModel a really powerful and convenient tool for dealing with lifecycle changes. Using LiveData as a type of ViewModel’s fields is a best practice to create a screen with mutable state of view data and async behaviour that immediately reacts to changes.
To get an instance of ViewModel, you can just use ViewModelProviders class:

It, in turn, refers to ViewModelStore to return a pre-existing instance if one exists.

The library also contains AndroidViewModel class that takes Application as an argument of the constructor.

Combination of these components solves main challenges faced by Android developers, such as boilerplate code or modular. To explore and check an example of this concept, I decided to create the sample project. It just gets a list of repositories from Github and shows one using RecyclerView.

As you can see, it handles configuration changes without any problems, and an Activity looks very simple:

How you have probably noticed, our activity assumes minimum responsibilities. ReposViewModel holds state and view data in the following way:

You can think of state as the following:
state: { isLoading: true, repositories: [], exception: null }
Transformations is an util class that has two methods: map
and switchMap
. Both take two arguments: source LiveData and a function, and create a new LiveData, which behaves according to the following logic: it reacts to changes of source LiveData and applies the given function.
I also created a custom ReposLiveData:

It takes an instance of Repository and name of organization, loads data and set it up. A method onInactive()
is called when the number of active observers changes from 1 to 0 and gives opportunity to dispose Single of RxJava. ReposLiveData is an option on how to convert a live collection of RxJava to LiveData.
If you want to adapt Flowable to LiveData or vice versa, you can use LiveDataReactiveStreams class. To add it to your project you have to add next dependency:
compile 'android.arch.lifecycle:reactivestreams:' + rootProject.archLifecycleVersion
It’s util class that contains two methods:
public static <T> LiveData<T> fromPublisher(final Publisher<T> publisher)
and
public static <T> Publisher<T> toPublisher(
final LifecycleOwner lifecycle, final LiveData<T> liveData) {
Let’s move to implementation of Repository pattern and meet with another component from AAC.

Our app invokes a request to Github API and saves the result to local storage. It gives us opportunity to get existing data from a database, without a need to use expensive requests to a web service, consequently our app can also work without an Internet connection.
I chose the new Room Persistence Library as local datastore to explore it. Room provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.
Room has the following benefits:
- It’s ORM and you don’t have to write boilerplate code to convert Cursor to POJO or one to SQL queries.
- Compile-time verification of raw SQL queries
- You can use the power of a relational database
Drawbacks:
- You have to write raw SQL
- It’s not as fast as NoSQL
There are 3 major components in Room:
- Database

The annotation defines the list of entities and schema’s version. The class’s content defines the list of data access objects (DAOs) in the database.
To create a database in an async way, I use singleton and Builder from Room class.

We can use isDatabaseCreated
LiveData to detect the moment when the process of creation will finish.
Finally, we can invoke createDb
method from App class.

- Entity
Represents a class that holds a database row.

There are a lot of annotations that can be helpful for you, such as @ColumnInfo(name = "first_name"), @Insert, @Delete, @Ignore, @ForeignKey
and so on and so forth.
Please notice, that Entity doesn’t require empty constructor, unlike RealmObject and we can use it as a data class. However I received this error if I added more than two constructors with args.
/entities/Repo.java:51: error: Room cannot pick a constructor since multiple constructors are suitable. Try to annotate unwanted constructors with @Ignore.
- DAO
This component represents a class or interface as a Data Access Object (DAO). DAOs are the main component of Room and are responsible for defining the methods that access the database. The class that is annotated with @Database
must contain an abstract method that has 0 arguments and returns the class that is annotated with @Dao
. When generating the code at compile time, Room creates an implementation of this class.

Traditionally, we use Retrofit to deal with HTTP, but in this sample, I decided to try another library, such as Fuel.
There are some main features of Fuel:
- Support of basic HTTP GET/POST/PUT/DELETE/HEAD in a fluent style interface
- Support of both asynchronous and blocking requests
- File download
- File upload (multipart/form-data)
- Cancellation of in-flight requests
- Request timeout
- Manager configuration using
FuelManager
- Debug log / cUrl log
- Support of response deserialization into plain old object (both Kotlin & Java)
- Automatic invocation of handlers on Android Main Thread when using Android Module
- Special test mode for easier testing
- RxJava 2.x support out of the box
Retrofit requires a lot of boilerplate code to create a Service and to add OkHttp. Get request with Fuel looks like this:

It’s all that we need to perform the request. Using FuelManager, we can set up interceptors or SSL certificates. So, it’s a really convenient and useful library.
Finally, our Repository looks like this:

Testability
I also added some sample of test.
Conclusions
Altogether, this set of libraries provides base components to create modular, testable and robust Android apps. If you don’t want to use all of them, you can pick and choose what you need. In this article, we have shown how to combine AAC with Repository pattern and how to create a robust Android app. Kotlin is a new official programming language for Android developers, and it works fine with AAC. Source code is available on Github. Please check it out. Thanks for reading :)