Android Architecture Components – a collection of libraries that helps to create applications. See how to configure the project, model entities and create DAOs
During Google I/O 2017, Google introduced the Android Architecture Components – a collection of libraries that helps developers create applications. It includes:
The next two parts of this article will include an introduction to the first library mentioned above – Room. Firstly, I’ll show you how to configure the project, model entities and create DAOs. In the next parts, we will bring together Room, RxJava and the rest of Android Architecture Components libraries in order to create a more flexible and maintainable app.
Room gives us a great alternative for standard, boilerplate SQLite operations. Room isn’t an ORM such as for example GreenDAO. It only provides an extra layer over SQLite. The main benefits of Room are:
While developing an app with Room, we need to implement all of three main components:
Communication between these three components is shown in the figure below:
Since we know what is Room and what does it consist of, it’s time to start creating our application. In this tutorial, we’ll try to create an application for saving our tasks and setting reminders to them. For every task, we are going to save some reminders with different priorities because there will be only one reminder notification per minute. So, after this short introduction – let’s start coding!
Firstly, Room isn’t a part of the Android environment, so we need to add a dependency in gradle. Android Architecture Components are available on the Maven repository. To add it to your project, open your project build.gradle and paste the maven repository url:
Open app build.gradle and paste the latest* Room dependencies in dependencies section:
Now, synchronise your project and voilà – you can use Room.
Before we get started with modelling our entities, we need to know some useful annotations and their attributes.
Now we can start coding. First of all, we need to model three classes – User, Task and Reminder as shown below:
Secondly, we can create the User class.
Let’s auto generate ids for each user. Set the autogenerate property to true. We also allow users to create one account per email For this, we’ve added @Index annotation and unique = true property.
Next, let’s create Task class.
We’ve got an autogenerated primary key. However, the most important is the declaration of @ForeignKey. It allows us to specify, what to do with all user tasks when the user deletes his account.
Now, we need to create Reminder class, which is very similar to Task, except the new annotation – @TypeConverters. This annotation allows us to convert our custom data types to types which Room understands – all primitives and their boxed alternatives.
Converter class is just a simple class containing all converters. In our example, it’s Date to long and vice-versa.
Room does not allow to add object references between entities (for more see: https://developer.android.com/topic/libraries/architecture/room.html#no-object-references). A nice workaround is to create additional classes for resolving relations In our case these are user tasks and task reminders. We’ll use two annotations – @Embedded and @Relation.
As I mentioned before – @Embedded allows nested fields to be referenced directly in the SQL queries. @Relation describes relations between two columns. We have to specify the parent column name, entity column name and entity class. We don’t use @Entity annotation here. In the next step, we will use these classes to fetch data in our DAOs.
After hard work with entities, we can do something easier. Writing DAOs is really simple if we know the SQL syntax. I’ll show you only UserDao for brevity because Task and Reminder DAOs are very similar.
Every DAO interface must have @Dao annotations. For making queries we can use one of the bellows:
We are now using relations class – UserAllTasks. Due to the fact that we specify relations, we can get user and all of his tasks in a single query.
Finally, the last stage – creating a db (even easier than creating DAOs). All we need to do is to create an abstract class, which extends RoomDatabase and annotate this class by @Database. Furthermore, we have to pass which entities we want to use, specify the version of our db, create methods to return DAOs and build a database. All of these steps are shown below:
In the code above, I’ve implemented a simple singleton, but a better solution is to inject the database by Dagger or different DI library.
NOTE: Two marked methods are added temporarily. The fallbackToDestructiveMigration() to avoid writing migrations and the allowMainThreadQueries() to allow making queries in the main thread. Ignoring this method will cause an exception (if the query will be executed on the main thread). In the next part of this Android Architecture Components tutorial, I’ll show you how to write migrations and integrate Room with RxJava to avoid main thread queries.
It’s just a simple example of how to use our db now:
The first part of articles about Android Architecture Components is a simple example of Room. Next time we’ll use Room, LiveData, RxJava and ViewModel at once to create a “robust, testable, and maintainable app”. If you have any questions feel free to ask in comments.
See the Android Data Binding tutorial to learn more about Android Architecture Components.