Realm Mobile Database is an alternative to SQLite. Realm Mobile Database is much faster than an ORM, and often faster than raw SQLite.
Offline functionality, Fast queries, Safe threading, Cross-platform apps, Encryption, Reactive architecture.
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
Add the following right at the top of your app level
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
Every synchronous query method (such as
findAllSorted()) has an asynchronous counterpart (
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).
Setting up an instance
To use Realm you first need to obtain an instance of it. Each Realm instance maps to a file on disk. The most basic way to get an instance is as follows:
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:
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:
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
Note that all changes to data must happen in a transaction. Another way to create an object is using the following pattern:
Querying the database
All books having id greater than 10:
Deleting an object
For example, we want to delete all books by Taylor Swift:
List of primitives (RealmList
Realm currently does not support storing a list of primitives. It is on their todo list (GitHub issue #575), but for the meantime, here is a workaround.
Create a new class for your primitive type, this uses Integer, but change it for whatever you want to store.
You can now use this in your
If you are using
GSON to populate your
RealmObject, you will need to add a custom type adapter.
Realm models must extend the
RealmObject base class, they define the schema of the underlying database.
Supported field types are
byte, links to other
RealmList<T extends RealmModel>.
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)
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
In that case, methods like
person.addChangeListener() are replaced with
Limitations are that by a
RealmObject can be extended, and there is no support for
It is important that a managed RealmObject class can only be modified in a transaction. A managed RealmObject cannot be passed between threads.
In order to sort a query, instead of using
findAll(), you should use
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
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
The Try with resources can be used only from KITKAT (minSDK 19)
Using Realm with RxJava
For queries, Realm provides the
realmResults.asObservable() method. Observing results is only possible on looper threads (typically the UI thread).
For this to work, your configuration must contain the following
Afterwards, you can use your results as an observable.
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).
For writes, you should either use the
executeTransactionAsync() method, or open a Realm instance on the background thread, execute the transaction synchronously, then close the Realm instance.