Introduction
If you have been keeping up with the latest trends in Android development, you’ve probably heard of Realm. Realm is a lightweight database that can replace both SQLite and ORM libraries in your Android projects.
Compared to SQLite, Realm is faster and has lots of modern features, such as JSON support, a fluent API, data change notifications, and encryption support, all of which make life easier for Android developers.
In this quick tip, you are going to learn the basics of Realm for Android. In this tutorial, I will be useing Realm v0.84.1.
1. Adding Realm to a Project
To use Realm in an Android project, you need to add it as a compile
dependency in the app module’s build.gradle file.
compile 'io.realm:realm-android:0.84.1'
2. Creating a Realm
A Realm is similar to a SQLite database. It has a file associated with it, which, once created, will persist on Android’s file system.
To create a new Realm, you can call the static Realm.getInstance
method from inside any Activity
.
Realm myRealm = Realm.getInstance(context);
Note that calling Realm.getInstance
, without passing a RealmConfiguration
to it, results in the creation of a Realm file called default.realm.
If you want to add another Realm to your app, you must use a RealmConfiguration.Builder
object and give the Realm file a unique name.
Realm myOtherRealm = Realm.getInstance( new RealmConfiguration.Builder(context) .name("myOtherRealm.realm") .build() );
3. Creating a RealmObject
Any JavaBean can be stored in a Realm once it extends the RealmObject
class. If you are wondering what a JavaBean is, it is simply a Java class that is serializable, has a default constructor, and has getter/setter methods for its member variables. For example, instances of the following class can be easily stored in a Realm:
public class Country extends RealmObject { private String name; private int population; public Country() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getPopulation() { return population; } public void setPopulation(int population) { this.population = population; } }
If you want to use a member variable of a RealmObject
as a primary key, you can use the @PrimaryKey
annotation. For example, here’s how you would add a primary key called code to the Country
class:
@PrimaryKey private String code; public String getCode() { return code; } public void setCode(String code) { this.code = code; }
4. Creating Transactions
While reading data from a Realm is very simple, as you will see in the next step, writing data to it is slightly more complex. Realm is ACID compliant and to ensure atomicity and consistency, Realm forces you to execute all write operations inside a transaction.
To start a new transaction, use the beginTransaction
method. Similarly, to end the transaction, use the commitTransaction
method.
Here’s how you would create and save an instance of the Country
class:
myRealm.beginTransaction(); // Create an object Country country1 = myRealm.createObject(Country.class); // Set its fields country1.setName("Norway"); country1.setPopulation(5165800); country1.setCode("NO"); myRealm.commitTransaction();
You might have noticed that country1
was not created using the constructor of the Country
class. For a Realm to manage an instance of a RealmObject
, the instance must be created using the createObject
method.
If you must use the constructor, don’t forget to use the copyToRealm
method of the relevant Realm
object before you commit the transaction. Here’s an example:
// Create the object Country country2 = new Country(); country2.setName("Russia"); country2.setPopulation(146430430); country2.setCode("RU"); myRealm.beginTransaction(); Country copyOfCountry2 = myRealm.copyToRealm(country2); myRealm.commitTransaction();
5. Writing Queries
Realm offers a very intuitive and fluent API for creating queries. To create a query, use the where
method of the relevant Realm
object and pass the class of the objects you are interested in. After creating the query, you can fetch all results using the findAll
method, which returns a RealmResults
object. In the following example, we fetch and print all objects of type Country
:
RealmResults<Country> results1 = myRealm.where(Country.class).findAll(); for(Country c:results1) { Log.d("results1", c.getName()); } // Prints Norway, Russia
Realm offers several aptly named methods, such as beginsWith
, endsWith
, lesserThan
and greaterThan
, you can use to filter the results. The following code shows you how you can use the greaterThan
method to fetch only those Country
objects whose population
is greater than 100 million:
RealmResults<Country> results2 = myRealm.where(Country.class) .greaterThan("population", 100000000) .findAll(); // Gets only Russia
If you want the results of the query to be sorted, you can use the findAllSorted
method. As its arguments, it takes a String
specifying the name of the field to sort by and a boolean
specifying the sort order.
// Sort by name, in descending order RealmResults<Country> results3 = myRealm.where(Country.class) .findAllSorted("name", false); // Gets Russia, Norway
Conclusion
In this quick tip, you learned how to use Realm in an Android project. You saw how easy it is to create a Realm database, store data in it, and query it. To learn more about Realm for Android, you can go through its Java documentation.