RealmExample
A simple project demonstrating how to use Realm database for Android development.
Posted on May 31, 2018
Nowadays we have a lot of options when deciding to choose a database solution. We have different attractive options each of which has it's strengths and weaknesses. One I have found to be outstanding is Realm database. Realm database can be used by Android, IOS, React and even Xamarin developers.
Most applications today will need some sort of persistent data, sorting that out usually involves making the application more complex and adds more lines of code. Many engineering organizations are all too familiar with the pain of increased development complexity that results in longer cycles, overburdened resources, and an unwieldy code base. Realm, alongside other new database solutions, is solving this issue of complexity.
Realm simplifies your application architecture while giving you very powerful features. The Realm Platform is actually made up of two major components. The Realm Database and the Realm Object Server. According to the official documentation, these two components work in conjunction to automatically synchronize data enabling a lot of use cases ranging from offline apps to complex backend integrations. I am not going to cover the Realm Object Server in this article, therefore, you can read more about the Realm Object Server here.
One of the key factors that makes Realm so special is the fact that it was built for our modern mobile development demands, a lot of the solutions we use were not actually designed for phones, tablets or wearables:
For a very long time SQLite has been our main choice for persistence on mobile and even if it is not used directly it is used by many libraries that provides a convenience wrapper around it such as Couchbase Lite, Core Data, ORMLite, etc.
Realm also boasts of speed, according to the documentation, Realm is faster than even raw SQLite on common operations, while maintaining an extremely rich feature set.
Realm is also simple to use, here are some sample codes of how basic Realm transactions would look like:
For Java:
public class Dog extends RealmObject {
public String name;
public int age;
}
Dog dog = new Dog();
dog.name = "Rex";
dog.age = 1;
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
realm.copyToRealm(dog)
realm.commitTransaction();
RealmResults<Dog> pups = realm.where(Dog.class)
.lessThan("age", 2)
.findAll();
For Swift:
class Dog: Object {
@objc dynamic var name = ""
@objc dynamic var age = 0
}
let dog = Dog()
dog.name = "Rex"
dog.age = 1
let realm = try! Realm()
try! realm.write {
realm.add(dog)
}
let pups = realm.objects(Dog.self).filter("age < 2")
For Javascript:
class Dog {}
Dog.schema = {
name: 'Dog',
properties: {
name: 'string',
age: 'int',
}
};
let realm = new Realm();
realm.write(() => {
realm.create('Dog', {name: 'Rex', age: 1});
});
let pups = realm.objects('Dog').filtered('age < 2');
For Xamarin:
public class Dog : RealmObject
{
public string Name { get; set; }
public int Age { get; set; }
}
var realm = Realm.GetInstance();
realm.Write(() =>
{
realm.Add(new Dog
{
Name = "Rex",
Age = 1
});
});
var pups = realm.All<Dog>().Where(d => d.Age < 2);
We are going to build a very simple application using Realm database. It is going to be an Android app. I will try to make it as simple as I can so anyone can relate to it and implement it on whatever platform they wish.
The app we are going to make just does basic database operations, this is just to give you an overview of what to expect when working with Realm.
We have an Edittext view for the name and age of a user to be inserted into the database. Then below those is an add button which inserts the user name and age into the database. There is also the filter button which queries the database for specific users.
Add the class path dependency to the project level build.gradle file.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.1.2'
classpath "io.realm:realm-gradle-plugin:5.1.0" //todo (1) add realm dependency
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
Apply the realm-android plugin to the top of the application level build.gradle file.
apply plugin: 'com.android.application'
apply plugin: 'realm-android' //todo (2) add realm plugin
android {
compileSdkVersion 27
defaultConfig {
...
Define your model class by extending RealmObject. It is similar to your everyday POJO classes.
import io.realm.RealmObject;
//todo (3) Define your model class by extending RealmObject
public class User extends RealmObject{
private String name;
private int age;
public User() {
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
To get started, you will need to initialize Realm, this is needed just once per application, so a good place to do this is in onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
//todo (4) Initialize Realm (just once per application)
Realm.init(this);
//todo (5) Get a Realm instance for this thread
Realm realm = Realm.getDefaultInstance();
...
So now all is set and ready. The next step is to add a new user with a name and age. They are added by clicking the 'ADD' button as shown in the diagram above. The ID's for the Edittext views name, age are name_txt and age_txt respectively, while the ID for the button is add_btn.
add_btn.setOnClickListener(v -> {
// write operations in Realm must be wrapped in transactions.
realm.beginTransaction();
User user = realm.createObject(User.class); //todo Create a new object
user.setName(name_txt.getText().toString()); //todo get user name from Edittext and store in user object
user.setAge(Integer.valueOf(age_txt.getText().toString())); //todo get user age from Edittext and store in user object
realm.commitTransaction();
// commit transaction
Toast.makeText(this, "User added", Toast.LENGTH_LONG).show();
clearText();
});
When beginning a Realm write operation, it has to be wrapped in transactions. Basically, at the end of a write operation, you can either commit the transaction or cancel it. Committing a transaction writes all changes to disk. If you cancel a write transaction, all the changes are discarded.
If you noticed, the first samples in this article used copyToRealm() to add a new Object, both methods will insert data into the database.
In the code above, we simply created a new object from the User class which extends RealmObject, we set the values and voila! we have inserted that data. I haven't hidden any extra code or class from you, that is really all it takes to perform a write operation.
So now that we can insert our lovely data, the next question is how do we get it out π€.
Well, if you thought the process of inserting data looked cool, wait and see how we retrieve it. Supposed you wanted to get all the users whose age was less than 45 this is how that query would look like:
RealmResults<User> result = realm.where(User.class)
.lessThan("age", 45)//find all users with age less than 45
.findAll();//return all result that reach criteria
Now ain't that splendid? After doing that you could loop through the realm results and get the values for example:
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < result.size(); i++) {
stringBuilder.append(result.get(i).getName() + " ");
}
I have just scratched the surface, Realm can do much more than I have demonstrated, this was just meant to be an introduction. You can check the documentation for more information on queries, filtering, multi-threading, testing and much more.
You can find the full source code of the sample app above here:
A simple project demonstrating how to use Realm database for Android development.
Posted on May 31, 2018
Sign up to receive the latest update from our blog.