Example of Realm with MVP and Dagger

Mateusz BudzarAndroid Developer

More and more complicated

In my previous article I’ve shown you a simple example of how to use Realm database. However projects that we are working on are definitely more complicated. We use different libraries like ButterKnife, EventBus, Retrofit, Dagger and so on. We also try to make our app more testable i.e. with the use of MVP pattern. All these things should make our life easier, sure, but it’s not that obvious how to implement it correctly – especially for the first time. In below example I tried to use Realm database in app with MVP architecture and Dagger library.

Now we are ready to provide Realm instance to each Activity. ApplicationModule also provides RealmService object but about that later.

MVP

With the use of MVP pattern we try to make our views like Jon Snow – they should know nothing. Views should take care only to show something on screen or get taps and pass them on. Without ‘thinking’ and any logic. So views shouldn’t know about Realm instance either. We have to pass Realm instance to Presenter but dealing with database directly in it could be a huge burden. RealmService solves the problem.

BooksModule simply injects BooksPresenter with RealmService to the BooksActivity.

RealmService

As long as we do read queries we are allowed to do them on UI thread and use injected Realm instance field.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

publicclassRealmService{

privatefinalRealm mRealm;

publicRealmService(finalRealm realm){

mRealm=realm;

}

publicvoidcloseRealm(){

mRealm.close();

}

publicRealmResults<Book>getAllBooks(){

returnmRealm.allObjects(Book.class);

}

//other methods

}

The problem occurs with database modifications like write or update. If write operation is not a simple one we should do it on background thread.

We can either use an AsyncTask and in doInBackground() make write operation with new Realm instance between Realm.beginTransaction() and Realm.commitTransaction() or use method Realm.executeTransaction(…).

The first idea is not a good one for our architecture. All database operation should be doing outside the View, so the AsyncTask should be implemented in Presenter or some kind of service, but we also don’t want Android framework in any classes except Views.

Method execute() is called in background thread. If there was no exception during operations on database then onSucces() method is called, if not – onError(…). Notice that in execute() body the new instance of Realm is used.

Summary

It is possible to use Realm in MVP architecture. Even if we can’t use Realm instance in different thread than it was created, we can use async transactions mechanizm with callbacks which Realm provides. Opening and closing Realm instance in each Activity and Fragment is not a problem as long as we use Dagger and some base component which views have to inherit.

Do you have any other ideas how to use Realm with MVP? Feel free to comment.