Android Architecture Components: Room — Introduction

Introduction

Recently Google announced a set of new libraries for designing Android application’s architecture — Android Architecture Components. It’s a collection of libraries, due to which you’re able to create consistent, fully testable and maintainable app. Sounds good?

  • Lifecycle Components (including LiveData, ViewModel, LifecycleObservers and LifecycleOwners) — a library for handling your app’s lifecycle
  • Paging Library — a small library to help you load data gradually

What’s Room?

Room is a database library. From the documentation:

Why another Android database?

Of course, there are a lot of different options to have database in your application. You can either create it by using native solutions (e.g. SQLiteOpenHelper), or use one of the existing library (greenDAO, OrmLite, Realm and much more). However, none of these solutions has all these advantages:

  • very little boilerplate code
  • full integration with other Architecture components (like LiveData)

How to use it?

Step #1 — add dependencies

Ok, let’s assume I convinced you to use Room in your project. How to do it? At first, we need to add Google Maven repository to our build.gradle file:

allprojects {
repositories {
jcenter()
google()
}
}
implementation 'android.arch.persistence.room:runtime:1.0.0'
annotationProcessor 'android.arch.persistence.room:compiler:1.0.0'

Step #2— create entity

No we’re ready to start creating our database. Let’s assume we’d like to get all of the repo for specific user from Github. At first, we need to create our Repo entity:

import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.support.annotation.NonNull;

@Entity
public class Repo {
@PrimaryKey
public final String id;
public final String name;
public final String url;

public Repo(int id, String name, String url) {
this.id = id;
this.name = name;
this.url = url;
}
}
  • at least one (*) @PrimaryKey field (if it’s non primitive, should be annotated with @NonNull)

Step #3— create DAO

Then, we need to create DAO for our entity. DAO stands for Data Access Object, so it’s a way of telling our database how to put the data:

import android.arch.persistence.room.Dao;
import android.arch.persistence.room.Delete;
import android.arch.persistence.room.Insert;
import android.arch.persistence.room.Query;
import android.arch.persistence.room.Update;
import java.util.List;

@Dao
public interface RepoDao {

@Query("SELECT * FROM repo")
List<Repo> getAllRepos();

@Insert
void insert(Repo... repos);

@Update
void update(Repo... repos);

@Delete
void delete(Repo... repos);
}
  • @Query for creating queries — we can make select from the database (e.g. get all repos)
@Insert
void insert(Repo... repos);

@Insert
void insert(Repo repo);

@Insert
void insert(List<Repo> repoList);
@Query("SELECT * FROM repo")
List<Repo> getAllRepos();

@Query("SELECT * FROM repo WHERE id=:id")
Repo getRepo(int id);

@Query("SELECT * FROM repo")
Cursor getRepoCursor();
@Query("SELECT * FROM repo WHERE name=:name")
List<Repo> getReposByName(String name);

@Query("SELECT * FROM repo WHERE name=:name LIMIT :max")
List<Repo> getReposByName(int max, String... name);

Step #4— create database

Now it’s time to create our database:

import android.arch.persistence.room.Database;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.RoomDatabase;
import android.content.Context;
import android.support.annotation.NonNull;

@Database(entities = { Repo.class }, version = 1)
public abstract class RepoDatabase extends RoomDatabase {

private static final String DB_NAME = "repoDatabase.db";
private static volatile RepoDatabase instance;

static synchronized RepoDatabase getInstance(Context context) {
if (instance == null) {
instance = create(context);
}
return instance;
}

private static RepoDatabase create(final Context context) {
return Room.databaseBuilder(
context,
RepoDatabase.class,
DB_NAME).build();
}

public abstract RepoDao getRepoDao();
}
  • class to be abstract and extend from RoomDatabase class
  • class have an abstract method with no parameters and returns the class that is annotated with @Dao (in our case: getRepoDao())

Step #5— here’s your database!

We’re finally able to make queries and inserts to our database. Let’s see this in practice!

RepoDatabase
.getInstance(context)
.getRepoDao()
.insert(new Repo(1, "Cool Repo Name", "url"));
List<Repo> allRepos = RepoDatabase
.getInstance(MainActivity.this)
.getRepoDao()
.getAllRepos();

Extra

If you’d like to check Room in practice, but you don’t want to create a whole new project, you can try Google Codelabs for Room. There you’ll also find other cool topics, e.g. Type Converters.

Flutter GDE / Android & Flutter Developer / blogger / speaker / cat owner / travel enthusiast

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store