Realm in Android – simple example

Mateusz BudzarAndroid Developer

What is Realm?

Realm is another type of database in Android. But, what is very important, Realm doesn’t use SQLite. If you use ORMLite or ActiveAndroid or any other similar library, your data is stored in SQLite database, because these libraries give us only an overlay on SQLite. With Realm there is no SQLite at all. Thanks to that Realm is very fast and you are even allowed to write the data in UI thread (mostly).

Gradle

Add the following line to your dependencies.

1

2

3

4

dependencies{

compile'io.realm:realm-android:0.87.4'

//other dependencies

}

Simple example

I’ve created very simple project to show how the database works and how to use it. Application consists of one Activity (container) and two Fragments. First Fragment allows us to add a book which is stored in database (MyEditionFragment) and the second one shows a list of all books from the database (MyListFragment). And that’s it.

RealmObject

To use your object as a Realm object you have to simply extend RealmObject class.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

publicclassMyBookextendsRealmObject{

@Required

privateStringtitle;

publicStringgetTitle(){

returntitle;

}

publicvoidsetTitle(finalStringtitle){

this.title=title;

}

}

Annotation @Required means that title cannot be null.

CRUD operations

All of the CRUD operations are made with the use of Realm instance. How?

Each operation on database which is not the read operation, has to start with Realm.beginTransaction() and to end with Realm.commitTransaction(). There are two arguments for that – our data will always be in consistent state and it also ensures the thread safety. If you forget to commit your changes, they will not be saved. You can also cancel the transaction by calling Realm.cancelTransaction().

3. According to Realm documentation it is important to close all of the Realm instances when we are done with them.

1

2

3

4

5

@Override

publicvoidonDestroy(){

super.onDestroy();

mRealm.close();

}

Auto-update magic

Above example shows how to add or remove some object in Realm but the real magic happens in the MyListFragment – the one with the list of books.

So what we are trying to do is to update our list when a new book is added or existing one is removed.

1. Get a Realm instance in Fragment.onCreate() and close it in Fragment.onDestroy().

Query Realm.allObjects(ClassName.class) returns RealmResults objects. It is very important to understand that the data in Realm is never copied. We get a list of references and we work on a original objects.

3. Add a RealmChangeListener to RealmResults.

1

2

3

4

5

6

7

8

9

publicMyListAdapter(RealmResults<MyBook>books){

mBooks=books;

mBooks.addChangeListener(this);

}

@Override

publicvoidonChange(){

notifyDataSetChanged();

}

And here is where the magic happens. If we add a new book in MyEditionFragment, list in MyListFragment will refresh automatically. All we did is we added a listener which will inform us when the data, to be more precise – the books set, is changed. This is all it gives us and this is all we need. Method onChange() has no object (or list of objects) which was changed because we don’t need that information. We already have it. As it was said above, Realm data is never copied. So when a new book is added in MyEditionFragment, the list in MyListFragment adapter will be informed that something in books set was changed but mBooks object has been already automagically updated by Realm. All we have to do now is to update the view.

Troubleshouting

Hungarian notation

If you use the ‘m’ prefix in your class fields be aware that getters and setters should also have the ‘m’ character in their names. Read more.

Schema migration

During development database schema is changing all the time. If you have some data stored in database any future schema changes will cause a migration problems. You can either handle the migration changes or delete .realm file with all the data if Realm detects migration problems.