Android Architecture Components — Room and Kotlin

ritesh singh
MindOrks
Published in
5 min readJan 7, 2018

In this article, we will be looking into one of the library of the architecture component called Room.

In my last two posts, I had written about Understanding Android Networking Library Retrofit 2 and Dependency Injection Using Dagger 2 using Kotlin, with the help of a sample app called Weather Application. I will be using the same application here, to understand Room.

What is Android Architecture Components?

It’s a collection of libraries that helps you design robust, testable and maintainable applications.

What is Room?

Room is a persistence library provides an abstraction layer over SQLite to allow fluent database access while harnessing the full power of SQLite.

It’s basically a wrapper above SQLite.

Why to use Room?

— Offers compile-time check.

— Fits well with LiveData, live monitoring using LiveData.

— Testing different components in Room is easy.

— Easy to use and implement.

— Decrease the amount of boilerplate code.

Before, getting into the implementation part, let’s understand the basic components of Room.

There are basically 3 major components in Room.

  1. Entity :- A Java or a Kotlin class which represents a table within the database.
  2. DAO :- DAO stands for DATA ACCESS OBJECT. This is basically an interface, which contains the methods like getData() or storeData() etc.. which are used for accessing the database. This interface will be implemented by the Room.
  3. Database :- This is an abstract class that extends RoomDatabase, this is where you define the entities (tables)and the version number of your database. It contains the database holder and serves as the main access point for the underlying connection.

The image below shows the components relationship with the rest of the app.

https://developer.android.com/training/data-storage/room/index.html

Now, coming to the implementation part.

How to use Room?

  • Add the required room dependencies.
  • Now, we need a table for our database with few required table columns. Let’s add an entity class.

Few points to be noted here

* . The class should be annotated with Entity, this is how Room identifies, For each entity you create, a table is created with the associated Database. By default, Room creates a column for each field, but you can avoid this for few fields by using Ignore annotation.

* . Each Entity, must define at least 1 primary key. You need to annotate the field with PrimaryKey annotation.

* . By default Room uses the class name as the table name. You can give custom name by using tableName property.

There are many things which you can do like relationship between entities or creating a nested objects or multiple primary keys.

Check out here for more on the same.

  • Now, we need a DAO (Data Access Object), which will be used for accessing the database.

Few points to be noted here

* . To interact or say access we need an interface annotated with DAO. This is how Room figures out. Each DAO includes methods that offer abstract access to your app’s database.

* . By accessing a database using a DAO instead of a query builder or direct queries, you can separate out different components of your database architecture.

* . DAO allows you to easily mock database access as your test app.

* . A DAO can be either an interface or an abstract class. In case of an abstract class, it can optionally have an constructor that takes RoomDatabase as its only parameter.

* . Room creates each DAO implementation at compile time.

You, can do so much more with the DAO, like passing parameters into the query, returning subsets of column, or passing a collection of arguments and more.

Check out here for more detail on the same.

  • Finally, we need a DatabaseClass, annotated with Database. The Database class establishes a logical grouping between the DAO interfaces. It also defines the required version number, which is used to track and implement database migrations.

Few things to be noted here

* . You should follow the singleton design pattern when instantiating an AppDatabase object, as each RoomDatabase instance is fairly expensive, and you rarely need access to multiple instances.

* . The class should be abstract and should extend RoomDatabase.

If you try running the above code with the created database above, your app will crash as the operation performed is on the main thread. By default, Room keeps a check of that and doesn’t allow operations on the main thread as it can makes your UI laggy.

You can avoid that by using AsyncTask or Handler or Rxjava with io schedulers or any other options which puts the operation on any other thread.

There is one more options, which allows you to do the operation on the main thread. You can use the same for testing but should avoid . To do that you can add allowMainThreadQueries() on the builder.

And you can also use inMemoryDatabase, for testing. This database will only exist with the application process, one the process dies, the database is cleared. All you need to do is use inMemoryDatabaseBuilder() instead of using databaseBuilder().

We are done creating all the three components. Now, lets make use of it.

I have created a worker handler which takes care putting the queries and updates in worker thread.

This is how my homeActivity looks like.

Notice the fetchWeatherDataFromDb() and insertWeatherDataInDb(), these functions are responsible for interacting with the database.

I have created a Runnable for both which are posted in background thread via worker handler and result on main thread via UI handler.

And we are done…!!!!

You can find the whole working code here.

In my next article, I will writing about using Room with RxJava and observe changes using LiveData. Stay tuned.

--

--