Pre requisite of this tutorial is that you must have knowledge of databases and basic CRUD operations with them. Knowledge of SQLite in Android is recommended but not necessary.

This tutorial will get you started with Room in Android by teaching you all the CRUD operations and related details required to use this amazing library in your projects. Throughout this tutorial we will build a contact saving application. The complete code is available at this Github repo. The best way to learn is by doing, so open the repo or clone it in your machine and make a new project in which you will add all the functionality. If at any point you get stuck, refer the completed code.

Here is what the UI looks like in the completed app. I will not be teaching you how to make the UI, you will have to refer to the code for that.

room

room

What is Room?

Room is an ORM (object relational mapper) for SQLite database in Android. It is part of the Architecture Components released by Google. At its core, all the code that you write related to Room will eventually be converted to SQLite code. Room allows you to create and manipulate database in Android more quickly. See it as an abstraction layer on top of inbuilt SQLite database.

Setting up the project

Create a new Android Studio Project, I named it ‘ContactsRoom’.

In the your app level  build.gradle file, add the following dependencies.

In your project level  build.gradle file make sure in the repositories section  google() is added.

Now sync the project and you are ready to go.

Creating schema

In Room you don’t have to write a class extending SQLiteOpenHelper or write table creation queries. Room creates the tables automatically for you. In Room we define a simple POJO class and annotate it with  @Entity . Here we will create a model class for contacts with all required annotations.

As you can see this is a simple java class with some annotations, nothing too complicated.

In the  @Entity annotation we have provided a custom tableName, you can leave out this field. If you don’t provide a tableName, Room will use the name of class as the table name i.e. ‘Contact’ (with capital C).

When you annotate a class with  @Entity you must provide a no arguments constructor. Here as we have not provided any constructor, java automatically inserts the default (no arguments) constructor at compile time.

If a class is annotated with  @Entity then you have to specify a primary key using the  @PrimaryKey annotation. Here we use the  phoneNumber field as the primary key.

Room will take our Contact  class and create a corresponding table with the provided fields as columns.

If in any case you don’t want a field to be considered in the table schema then just annotate it with  @Ignore , by doing this Room will not persist this field.

By default room will use the field names are names of columns in tables, but you can change this by using   @ColumnInfo(name = "phone") annotation on the field. Take a look at all options provided by ColumnInfo annotation.

Creating DAO (data access object)

Now will we create a DAO(data access object) for doing operations on our Contact table. You can take an in-depth look at the concept of a DAO, in short it is just an abstract class that defines a bunch of operations relating to an object.

Below is a simple DAO (interface) with CRUD operations on Contact.

To create a DAO, you have to create an interface and annotate it with @Dao .

Insert operation

To create an insert operation just define a method that takes  Contact  or Contact... (varargs) as a parameter and annotate the method with @Insert .

Update Operation

Similar to insert operation, just create a method that takes  Contact or Contact...  (varargs) as a parameter and annotate the method with @Update .

Delete Operation

Similar to insert operation, just create a method that takes  Contact or Contact...  (varargs) as a parameter and annotate the method with @Delete .

Running Queries

While Room provides annotations for simple operations on databases, it also provides the ability to custom written queries. So if you wanted to get all the contacts, you would write a select query as below.

Use the @Query annotation and pass in the query you want to run. Since we want all the contacts in the table, we will set the return type to a list of contacts,  List<Contact> . Remember when you ran a query in SQLite it would return a Cursor object, then you would have to iterate over the cursor and fetch all the values while adding them to a list. Room does all of this behind the scenes, it will run the query, convert the cursor result to list and return the list to you. Pretty amazing!

Now suppose you want to write a query to get the Contact details associated with a particular phone number. Here is how you would write that.

You will pass the phone number in the method arguments and use it inside the query by prefixing the parameter name with  : (colon). The return type here is Contact  because we are looking for a single contact.

Below is the complete code for DAO interface.

Room will take this interface and implement all the methods for you, all you have to do is specify the operations using the appropriate annotations.

Building the database

Now all we have to do is tie up all of the above classes and interfaces. For that we will create an abstract class named  AppDatabase that will extend  RoomDatabase . This will be the class that will give us access to the implementation of the DAO interface.

You will have to annotate this abstract class with @Database , specifying all the entities that you have created and the database version.

Inside you will specify an abstract method with return type of ContactDAO . Room will provide us with complete implementation of this abstract class along with all specified abstract methods.

Now wherever you want the instance of  AppDatabase , write the below code.

Room.databaseBuilder() takes 3 arguments:

  1. Reference to Context .
  2. Abstract database class to return the instance of.
  3. Name of the database.

You can see we have called a method  allowMainThreadQueries() on the builder, this is because by default Room doesn’t allow you to run queries on  MainThread , you will have to run them on a background thread. While Google recommends to run database queries on background threads , it is out of scope of this article to teach that, so we use the  allowMainThreadQueries() method provided by Room which will allow the queries to run on MainThread .

After getting the instance of AppDatabase you can now get the ContactDAO by calling  getContactDAO() which you defined earlier and start calling the CRUD methods defined.

The complete code is available at this GitHub repo, I urge you to look at the code to get full understanding.

Never miss a post from TheTechnoCafe


Saving non-primitive types using Type Converters

In Room you can only save primitive types of the language. If you want to save a non-primitive type such as a  List or  Date , you would have to provide a type converter for it. With TypeConverter you tell Room how to convert the non-primitive type to a primate type. We will add a createdDate field of type  Date in our Contact  model.

If you try to run this code without providing a type converter, Room will give error during compilation.

In our case we will provide type converter for Date , we will convert  Date to  long . When writing a type converter, you will have to provide conversion both ways, i.e. in our case one converter that converts  Date  to long  and another that converts long  to Date .

Writing type converter is easy, all you have to do is write methods with appropriate return type, argument and annotate them with  @TypeConverter .

You you can see we have created a new class called DateTypeConverter with the required methods.

Now we have to tell Room to use these type converter. In our AppDatabase  class we will have to tell which type converter to use. We have to do this using the annotation  @TypeConverters .

Now you can run the application, with no problems.

That is it for this tutorial. We will cover more advance features about Room in the next tutorial.

Meanwhile here are some other articles that you might be interested in.

Move content to side in Drawer Layout

How to make Bottom Sheet In Android 

Add 360 Photo Viewer in your Android App

Hide Floating Action Button in when scrolling in Recycler View


Gurleen Sethi

How can I tell you about myself in just a few lines, to get to know me you can reach out to me, email, text, call, or any other method of communication you like. I am always there for you!

5 Comments

Shane · April 3, 2018 at 8:51 pm

Thank you, this is a great tutorial. How do you access Room info in the app? Whenever I try to do it, I get an error about not being able to run on UI thread and I can’t find a good tutorial for how to overcome that.

    Gurleen Sethi · April 9, 2018 at 5:55 pm

    When you are building you database make sure to add ‘allowMainThreadQueries()’.
    AppDatabase database = Room.databaseBuilder(this, AppDatabase.class, "db-contacts")
    .allowMainThreadQueries() //Allows room to do operation on main thread
    .build()

mejdi · April 24, 2018 at 11:04 am

thank you so much for this

reza esfandiay · May 1, 2018 at 3:31 pm

thank you my freind for this

indirajith · June 10, 2018 at 3:05 pm

how to handle relations in a proper way… documentation provided by google is not so clear … can you explain with it relationships… Anyway thanks for your tutorial.

Leave a Reply

Your email address will not be published. Required fields are marked *

4 × 1 =