Search code examples
androidrealmabstraction

Proper way to abstract Realm in Android apps


I'm trying out Realm.io in an Android app, though, to stay on the safe side, I would like to abstract the DB layer so that, in case of need, I can switch back to a standard SQLite based DB without rewriting most of the app.

I'm however finding it difficult to properly abstract Realm due to it's particular nature:

  • When tied to a realm, RealmObjects are proxies so I cannot pass them around as they were POJOs.
  • All Realm instances need to be properly opened and closed for every thread they are used in.

I've resorted to using the recent Realm.copyFromRealm() API instead of passing around RealmObjects tied to a Realm to get around these limitations but this way I think I'm loosing all the benefits of using realm (am I?).

Any suggestions?


Solution

  • I would try to answer your first confusion. There is really no need to pass around RealmObjects via intents, or in other terms no need of them being parcelable or serializable

    What you should do is to pass around particular primary id or other parameter of that particular RealmObject via intent, so that you can query that RealmObject again in next activity.

    For example suppose you pass primaryId while starting an activity,

    Intent intent = new Intent(this, NextActivity.class);
    intent.putExtra(Constants.INTENT_EXTRA_PRIMARY_ID, id);
    

    Now inside NextActivity get id from intent and simply query RealmObject, i.e.,

    int primaryId = getIntent().getIntExtra(Constants.INTENT_EXTRA_PRIMARY_ID, -1);
    YourRealmObject mObject = realm.where(YourRealmObject.class).equalTo("id", primaryId).findFirst();
    

    See, you got your object in new activity, rather than worrying about passing the object around.

    I don't know what particular problem you're getting into regarding opening and closing realm objects. Did you try Realm's Transaction blocks? You don't need to rely on opening and closing if you use that.

    I hope this helps.

    Update

    Since you're looking for abstraction,

    Just create a class like DbUtils and have a method there like getYourObjectById and then pass above id and retrieve your object in return. That makes it abstract in a way. You can then keep that class and method, and just change method content if you ever switch to another database solution.