Remarks

When you use Realm, you must remember that you mustn't pass RealmObjects, RealmResults and Realm instances between threads. If you need a query on a given thread, open a Realm instance on that thread. At the termination of the thread, you should close the Realm.

LEGAL NOTE: You understand that the Software may contain cryptographic functions that may be subject to export restrictions,
and you represent and warrant that you are not located in a country
that is subject to United States export restriction or embargo,
including Cuba, Iran, North Korea, Sudan, Syria or the Crimea region,
and that you are not on the Department of Commerce list of Denied
Persons, Unverified Parties, or affiliated with a Restricted Entity.

Adding Realm to your project

Add the following dependency to your project level build.gradle file.

dependencies {
classpath "io.realm:realm-gradle-plugin:3.1.2"
}

Add the following right at the top of your app level build.gradle file.

apply plugin: 'realm-android'

Complete a gradle sync and you now have Realm added as a dependency to your project!

Realm requires an initial call since 2.0.0 before using it. You can do this in your Application class or in your first Activity's onCreate method.

Async queries

Every synchronous query method (such as findAll() or findAllSorted()) has an asynchronous counterpart (findAllAsync() / findAllSortedAsync()).

Asynchronous queries offload the evaluation of the RealmResults to another thread. In order to receive these results on the current thread, the current thread must be a looper thread (read: async queries typically only work on the UI thread).

The method Realm.getInstance() creates the database file if it has not been created, otherwise opens the file. The RealmConfiguration object controls all aspects of how a Realm is created - whether it's an inMemory() database, name of the Realm file, if the Realm should be cleared if a migration is needed, initial data, etc.

Please note that calls to Realm.getInstance() are reference counted (each call increments a counter), and the counter is decremented when realm.close() is called.

Closing an instance

On background threads, it's very important to close the Realm instance(s) once it's no longer used (for example, transaction is complete and the thread execution ends). Failure to close all Realm instances on background thread results in version pinning, and can cause a large growth in file size.

It's worth noting that above API Level 19, you can replace this code with just this:

try(Realm realm = Realm.getDefaultInstance()) {
// ...
}

Models

Next step would be creating your models. Here a question might be asked, "what is a model?". A model is a structure which defines properties of an object being stored in the database. For example, in the following we model a book.

Note that your models should extend RealmObject class. Primary key is also specified by @PrimaryKey annotation. Primary keys can be null, but only one element can have null as a primary key. Also you can use the @Ignore annotation for the fields that should not be persisted to the disk:

@Ignore
private String isbn;

Inserting or updating data

In order to store a book object to your Realm database instance, you can first create an instance of your model and then store it to the database via copyToRealm method. For creating or updating you can use copyToRealmOrUpdate. (A faster alternative is the newly added insertOrUpdate()).

If you add (or remove) a new field to your RealmObject (or you add a new RealmObject class or delete an existing one), a migration will be needed. You can either set deleteIfMigrationNeeded() in your RealmConfiguration.Builder, or define the necessary migration. Migration is also required when adding (or removing) @Required, or @Index, or @PrimaryKey annotation.

Relationships must be set manually, they are NOT automatic based on primary keys.

Since 0.88.0, it is also possible to use public fields instead of private fields/getters/setters in RealmObject classes.

It is also possible to implement RealmModel instead of extending RealmObject, if the class is also annotated with @RealmClass.

@RealmClass
public class Person implements RealmModel {
// ...
}

In that case, methods like person.deleteFromRealm() or person.addChangeListener() are replaced with RealmObject.deleteFromRealm(person) and RealmObject.addChangeListener(person).

Limitations are that by a RealmObject, only RealmObject can be extended, and there is no support for final, volatile and transient fields.

It is important that a managed RealmObject class can only be modified in a transaction. A managed RealmObject cannot be passed between threads.

Sorted queries

In order to sort a query, instead of using findAll(), you should use findAllSorted().

sort() returns a completely new RealmResults that is sorted, but an update to this RealmResults will reset it. If you use sort(), you should always re-sort it in your RealmChangeListener, remove the RealmChangeListener from the previous RealmResults and add it to the returned new RealmResults. Using sort() on a RealmResults returned by an async query that is not yet loaded will fail.

findAllSorted() will always return the results sorted by the field, even if it gets updated. It is recommended to use findAllSorted().

For asynchronous queries, you should filter the results by isLoaded(), so that you receive an event only when the query has been executed. This filter() is not needed for synchronous queries (isLoaded() always returns true on sync queries).