What is Realm?

Realm is a mobile database and a replacement for SQLite. Although is an OO database it has some differences with other databases. Realm is not using SQLite as it’s engine. Instead it has own C++ core and aims to provide a mobile-first alternative to SQLite. Realm store data in a universal, table-based format by a C++ core. This is what allows Realm to allow data access from multiple languages as well as a range of ad hoc queries.

Below are the advantages of Realm over SQLite:> faster than SQLite (up to 10x speed up over raw SQLite for normal operations)> easy to use> object conversion handled for you> convenient for creating and storing data on the fly> very responsive team

Also there are some disadvantages which might be taken into consideration:> no importing> still under active development> not a lot of content online> can’t access objects across threads

5. Create four packages named app, activity, adapters, model and realm and place your MainActivity.java under activity package. These packages helps in keeping your project organized.

6. Realms are the equivalent of a database: they contain different kinds of objects, and map to one file on disk. The most basic setup for realm is by calling:

// Obtain realm instance
Realm realm = Realm.getInstance(this);

Calling Realm.getInstance(context) makes it easy to get started with Realm. For more fine-grained control, it is possible to create a RealmConfiguration object that controls all aspects of how a Realm is created.

Create a class named MyApplication.java under app package. Here we setup the realm configuration.

8. In the model package add a class named Book.java. Realm data models are created by extending the the RealmObject base class. A Realm data model also supports public, protected and private fields as well as custom methods.

The usage of this class is quite simple. Let’s say if we want to get all the objects saved in the Book.class, all we need to do in the wanted activity is call the following getBooks() method from the RealmController.java class:

RealmController.with(this).getBooks()

11. Under the adapters package create the following classes: RealmRecyclerViewAdapater.java, RealmModelAdapter.java, RealmBooksAdapter.java and BooksAdapter.java.

12. Now that everything is set we can add code to the MainActivity.java

> Get realm instance from the RealmController.java> Setup the recycler. setupRecycler() method is used for this purpose.> Write some data in realm to be displayed in the recyclerView. setRealmData() method is used for this.> Refresh the realm instance> Set the realm adapter, get the realm data and pass it to the adapter

What is happening in this activity is when it is started, if there is no data in the realm, the setRealmData() method creates couple of objects and save it to the realm. After that realm instance is refreshed, the data is called with getBooks() and the adapter is notifyed about the changes:

Run the app, and you can now see the data displayed in the recycler view.

Performing Write, Update & Delete Operations

13. We have set the app to read the realm data, now let’s do some simple write, update and delete to the data. Under res ⇒ layout, create a layout named edit_item.xml. This layout will be use in a dialog interface for writing and updating.

Here we set and dialog on the floating action button to add new item. Run the following code and try to add some new data. (Note: you might need to uninstall and run the app again for the changes to take place) .

15. In order to make some update and delete actions open BooksAdapter.java and add the following code:

Here we set delete of a match through long click on the card item and update dialog on click. The removing of an item is very easy. All we need is the bellow code with the position passed to the realm.

// All changes to data must happen in a transaction
realm.beginTransaction();
// remove single match
results.remove(position);
realm.commitTransaction();

Now run the code again (uninstall or clear data if necessary ) and check the changes. Try updating or deleting some items.

Migration from SQLite

If you have currently have an app that uses SQLite and want to migrate to Realm, there is definitely some work involved. It is not a drop-in change. SQLite prefer a very normalized-form that doesn’t necessarily work the best with Realm. It’s better to rethink your schema and model it as objects.

Once you’ve modified the schema to work well with Realm however, it is much easier to migrate any existing data from SQLite. Just setup a migration (from version 0 to 1 of your Realm database), and in this migration, load your SQLite data into Realm objects and then just save them.

Or, if your data also resides on a remote server, you could just build the Realm database from scratch.
Before adopting Realm though, note that it must be considered as bleeding edge software, with an API that can have breaking changes in future versions.

Hi there! I am Founder at androidhive and programming enthusiast. My skills includes Android, iOS, PHP, Ruby on Rails and lot more. If you have any idea that you would want me to develop? Let’s talk: ravi@androidhive.info

Hi Ravi, Thanks for this tutorial.
After reading that Realm 1.0 has released, I tried to update your demo e.g. to 1.0, but it failed. Can you please provide an update on what changes should be done in gradle file, so that your e.g. can work with Realm 1.0.

Edit 1 – After some trial and errors, I figured out a way to sync gradle correctly with Realm 1.0. But now, I learnt that, all the adapters are throwing errors. It seems there has been some changes in coding of Realm. Please help.

Had to ask 🙂 Ravi has the best step by step tutorials for android I could find, and I couldn’t find any good sync adapter tutorial so far.

fadi qua

great example, if i have 2 classes, and the main class has list attribute of second class, how to deal with list attribute, to explain my idea, when i click on the item, it will open detail activity that display information of ” list ” attribute .. ?

Sabahat Sana

hi Ravi,please help me . i use realm with asynctask classes. And my app is crashed.

return this error:
Realm access from incorrect thread. Realm objects can only be accessed on the thread they were created.

Saad Saeed

i want to upload mp3 file into external database through my android application can anybody help.

Kuldeep Mishra

Hi Ravi, What is Pref Class in this tutorial, as you have not mentioned anywhere in this post. And also i try to get source code but always it is giving connection time out after try of 2-3 min…i think may be source code repository is down or something else…please help me to download source code for this post.

Hi @ravi8x:disqus @disqus_VqKuJF0GgB:disqus ,
On item delete i’m getting error plz help me…
Exception:
java.lang.IllegalStateException: Object is no longer managed by Realm. Has it been deleted?

I’m using realm 1.0.0. so there no constructor like this RealmBaseAdapter(Context context, RealmResults realmResults, boolean automaticUpdate) is available…no automaticUpdate parameter is there..

Zhuinden

You should not call `adapter.notifyDataSetChanged()` manually after you commit synchronous transaction on the UI thread. You should use a change listener on your results, and notify the adapter in that.

Harsh

Hi Ravi, How to scan business card and fetch information from the card? Do you have any example of that type? If not please develop this kind of example also as this will be more helpful for large amount of people including me as well.
Thanks.

Technically I wrote the README.MD file for that, and also at the top of the github page, it says this is a repository that accompanies my Medium article called “How to use Realm like a champ”

Collins Mucheru

Yeah, I saw all that before I wrote this comment. It’s just that some of the patterns you’ve used are pretty interesting and seem complex. I’ll have to do quite a bit of reading before I can even begin to comprehend what you’ve written. Thank you for the guide though.

Zhuinden

If anything is unclear, please specify it and I’ll add it to either the readme or the article or I’ll just make a third article that’s more tutorial-y. I’m monitoring my GitHub issues along with Realm-Java’s issues (which I check pretty often), so it’s likely I’ll respond at a reasonable time too

Collins Mucheru

You rewrote the tutorial and used complex concepts that rookies who come to help from Ravi barely understand. Let me break down what I don’t understand using the packages:

Nothing is happening in the MainActivity.java class, why?

application: I get what RealmInitialData.java does but the last 3 methods of the class are incomprehensible.

data.entity: I get what the Book.java Class does, but I can’t for the life of me get what RealmString.java does

paths.books: BooksActivity is understandable but the moment you implement BooksPresenter.ViewContract I’m lost and I can no longer understand BooksActivity. I’ve used the normal RecyclerViewAdapter so I kinda comprehend BooksAdapter.java. As for BooksAddBookView.java, BooksPresenter.java and BooksAddBookView.java I’m completely lost.

You seem to be using some interesting ‘veteran’ design pattern where even your presentation of views is modularized. I’m also new to Butterknife, which i think contributes to my scanty understanding of your poetic code.

Kindly make an effort to explain your work to us so we can also use Realm and Butterknife like champs. Thank you 🙂

Zhuinden

– Actually, lots of things are happening in MainActivity.

It creates the retained fragment (BooksScopeListener) that reference counts the activity count and opens/closes the Realm, and also creates the presenter instance (because retained fragments survive configuration change.) It also handles all events that have UI stuff going on – showing the “add book” dialog and the “edit book” dialog.

The AddBookView is the content of the dialog that’s inflated when you click the button that has to show a dialog in R.layout.edit_item’s XML.

Ravi did the same thing when he calls `inflater.inflate(R.layout.edit_item, null)` and sets this as the content of the dialog, except he set the click listeners manually after inflation, while I used a custom viewgroup instead which handles the binding with ButterKnife by default.

RealmString is pretty much a placeholder for the workaround of list of primitives (the workaround is `RealmList` ) but I don’t use that anywhere so heed it no mind.

`RealmInitialData` is a transaction. It inserts the elements into the Realm on first execution. The hashcode/equals just makes it so that every instance of `RealmInitialData` is the same. You’d have to do this for Migration too.

As for the presenter, well, it’s for your own benefit to delegate UI events to an external class and handle logic there instead of mashing everything in the Activity 🙂 For more info, you should to the GOOGLE CODELABS ANDROID TESTING guide, that is where `.ViewContract` is from.

Collins Mucheru

Thank you. You’ve cleared up for me what I was finding so hard to grasp. Now it’s so much simpler 🙂

honestly, this example is overcomplicated and outdated (0.82.1? The latest version is 1.1.1). I’ve updated this guide’s content to the latest Realm in my `realm-book-example` on Github.

Imam Kashif

Hello Ravi, I am using Sugar ORM for most of my apps. Please suggest me which one is better, Realm or Sugar ORM by satyan.

Zhuinden

Well, SugarORM is terrible. So Realm.

Nikolai Vasilev

I cannot understand why you request all these fragments, activities and application in the .with() method parameters. They are not used in the constructor at all…. All the different .with() methods are same and can be removed when the different parameter logic is not making difference

Zhuinden

Yeah, me neither, and it’s not even a proper solution because the Realm instance is never closed.

Mouad Ghandi

Thanks Ravi for this great article,
Please if you can underscores the utility of Prefs used in both “BooksAdapter” and “MainActivity” as Prefs.with(this).setPreLoad(true);
and how can we import it ? it still red in my project.

Best regards,

Kiran Benny Joseph

He is not included Prefs class. anyway thanks for the tutorial

Govarthanan Ravi

Hi can someone tell me what is the difference between adding library as classpath Vs adding it as a dependency

For example on Realm website they tell that inorder to include realm the following two steps should be followed
Step:1
dependencies {
classpath “io.realm:realm-gradle-plugin:1.1.0”
}
Step:2
apply plugin: ‘realm-android’ on build.gradle file

but in the above example ravi has asked to include
compile ‘io.realm:realm-android:0.82.1’

how do they both differ and in what means

In other words what is the difference between compile dependencies and classpath dependencies

Zhuinden

Using the `compile` dependency adds the project as a JAR, but adding it on the classpath adds it as a Gradle Plugin (which will add it through AAR)

Govarthanan Ravi

Thanks Zhuinden

Viet Nam

good

Vladimir Yerokhin

Nice article! Thank you!

Zhuinden

It’s actually very outdated.

Zhuinden

This article is outdated and not structured well, so I rewrote it in my `realm-book-example` repository on Github. (I can’t link it because if I do, the comment becomes “Pending”).

If we firstly call Controller.getInstance() it will return null so i believe this is not good pattern.you may observe that Controller.with(Application).getRealm() is the better approach .If you want to call in Adapter then Controller.with((Activity)context.getApplicationContext()).getRealm() is another approach.

How can i use checkbox on RecyclerView without save selected items into database? when i use model which is extends from RealmObject on recyclerview, for every change one of this model must be we use Transaction, 😐 but i dont want to save it to database, its only for getting user selected Items, i can’t resolve this problem

Zhuinden

I know this has been mentioned before, but you can contain temporary state in the adapter itself in a Map, and use onBindViewHolder based on that map rather than the objects directly.

They only allow the use of RealmList instead of Arraylist/List. However, RealmList or RealmList doesnt work is noted in this issue https://github.com/realm/realm-java/issues/575. I had to switch to couchbase to avoid too much refactoring