Realm with Android

Dheeraj Andra
MindOrks
Published in
5 min readApr 4, 2019
Image from https://realm.io/blog/realm-for-android/

Before we proceed with the implementation, we should understand the prerequisites for using Realm with Android:

  • Android Studio version 1.5.1 or higher
  • JDK version 7.0 or higher
  • A recent version of the Android SDK
  • Android API Level 9 or higher (Android 2.3 and above)

Note: Realm does not support Java outside Android(only Android Studio)

The link for the project is given below:

https://github.com/asdheeraj/Realm

Let’s understand the concept by creating a project.

First step would be including the realm dependencies in app’s build.gradle file and project level gradle file

buildscript {
ext.kotlin_version = '1.3.20'
ext.realm_version = '5.10.0'
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "io.realm:realm-gradle-plugin:$realm_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

Then, find the application level build.gradle file and add the following plugin:

apply plugin: 'realm-android'

Since we will be developing this in kotlin and if you find any error after modifying the app and project level gradle files and syncing them, let’s say, “configuration with name kapt not found”, please add the following plugin in application level build.gradle file:

apply plugin: 'kotlin-kapt'

Let’s understand why do we get this in error. Using Realm in our project will result in using some of the annotations like @PrimaryKey and since Kapt stands for Kotlin Annotation Processing Tool, it helps us in adding the respective annotations that are required for realm.

Since this is a database that we use in the Application Level in Android, we have to initialise the realm in the class that extends the Application class.

Note: Initialisation of Realm only has to be done once so as to use it throughout the application.

So, let’s create a class, say Realm Application class that extends Application Class.

class RealmApplication : Application() {

override fun onCreate() {
super.onCreate()
Realm.init(this)
}
}

Since we are creating our own Application subclass, we must add it to the app’s manifest file

<application
...
android:name=".RealmApplication"
...
/>

For working with Realm, we first need a Model class. This Model class should extend the RealmObject class. Let’s create a simple model class Student

open class Student(
var name: String?= null,
var age: Int?= null
) : RealmObject(){}

Why did we use the open keyword?

The reason is that adding “open” to a class in kotlin makes it available for inheritance and allows the class to be overridden. If we remove the open keyword here, we get an error stating cannot inherit from the final model class. Since the properties that are declared in the Model class are to be inherited and used by Realm, we should declare the class as open thereby, making it available for Inheritance.

Why did we initialise the variables to null?

When the realm object is initialised at the start, we can ensure that the default values for the variables in the data class are null. This is the concept of Function Default Arguments in Kotlin. Please refer the Function Default Arguments section in the link for more reference:

Is there any other way to use Realm in Android other than extending the RealmObject?

Instead of extending RealmObject, your classes can implement the RealmModel interface, adding the @RealmClass annotation:

@RealmClass
public class User implements RealmModel {
}

With this interface, all methods available on RealmObject become available through static methods. Note that a class that extends RealmObject does not need either the @RealmClass annotation or to implement RealmModel.

Let’s create a simple layout file containing two EditTexts to enter the name and age, one save button to save the data to Database and one TextView to view the response.

Let’s use the Material Design Library for the layout and hence please add the following dependency in application level build.gradle file

// Material Design
implementation "com.google.android.material:material:$support_library_version"

Please add the version number of support_library_version in project level build.gradle file.

ext {
support_library_version = '1.0.0'
}

Now let’s create the layout file as discussed

Once Realm is initialised, then we set its configuration. Set the default configuration for Realm by using the following code snippet:

override fun onCreate() {
super.onCreate()
Realm.init(this)
val config = RealmConfiguration.Builder().build()
Realm.setDefaultConfiguration(config)
}

To use the user defined configuration, define a Realm configuration object as follows:

// The RealmConfiguration is created using the builder pattern.
// The Realm file will be located in Context.getFilesDir() with name "myrealm.realm"
RealmConfiguration config = new RealmConfiguration.Builder()
.name("myrealm.realm")
.encryptionKey(getKey())
.schemaVersion(42)
.modules(new MySchemaModule())
.migration(new MyMigration())
.build();
// Use the config
Realm realm = Realm.getInstance(config);

Get the default instance of Realm by using the Code Snippet

private lateinit var realm: Realm

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
realm = Realm.getDefaultInstance()
.....
}

Note: To perform Database operations in Realm, make sure the code is written between beginTransaction and commitTransaction

realm.beginTransaction()
//added to delete the db once the activity is created. Only use this if required
realm.deleteAll()
realm.commitTransaction()

Here, realm.deleteAll() is only used to clear the db once the activity is created. Please use this statement carefully and only when required.

Now once the save button is clicked add the logic to save and read the data from the database as follows:

btn_save.setOnClickListener {
saveData()
}
private fun saveData() {
realm.executeTransactionAsync ({
val
student = it.createObject(Student::class.java)
student.name = edittextName.text.toString()
student.age = edittextAge.text.toString().toInt()
},{
Log.d(TAG,"On Success: Data Written Successfully!")
readData()
},{
Log.d(TAG,"On Error: Error in saving Data!")
})
}

private fun readData() {
val students = realm.where(Student::class.java).findAll()
var response=""
students.forEach {
response = response + "Name: ${it.name}, Age: ${it.age}" +"\n"
}
db_response.text = response
}

Here we are using the Kotlin extensions to access the UI widgets in the layout file thereby eliminating the findViewById boiler plate code.

That’s it! You have inserted and read the data successfully using Realm!

The link for the project is given below:

https://github.com/asdheeraj/Realm

Hope this blog has given you a clear idea on Realm in Android.

Thank you for your time!

Let’s connect on Twitter and LinkedIn

--

--