Gurleen Sethi
Gurleen Sethi

Reputation: 3502

How to maintain a single Realm instance throughout the app lifecycle and also close it?

How can I maintain a single Realm Instance throughout the complete lifecycle of the App and also close it.

I can achieve maintaining the instance using a singleton class, but then how do I close it when the app is closed?

Also, is it safe to not close Realm Instance once opened?

Upvotes: 5

Views: 1015

Answers (2)

EpicPandaForce
EpicPandaForce

Reputation: 81539

I tend to use a singleton RealmManager for the UI thread, and for background threads I open/close the Realm using a try-with-sources block.

So for UI thread:

public class RealmManager {
    private static final String TAG = "RealmManager";

    static Realm realm;

    static RealmConfiguration realmConfiguration;

    public static void initializeRealmConfig(Context appContext) {
        if(realmConfiguration == null) {
            Log.d(TAG, "Initializing Realm configuration.");
            setRealmConfiguration(new RealmConfiguration.Builder(appContext).initialData(new RealmInitialData())
                    .deleteRealmIfMigrationNeeded()
                    .inMemory()
                    .build());
        }
    }

    public static void setRealmConfiguration(RealmConfiguration realmConfiguration) {
        RealmManager.realmConfiguration = realmConfiguration;
        Realm.setDefaultConfiguration(realmConfiguration);
    }

    private static int activityCount = 0;

    public static Realm getRealm() {
        return realm;
    }

    public static void incrementCount() {
        if(activityCount == 0) {
            if(realm != null) {
                if(!realm.isClosed()) {
                    Log.w(TAG, "Unexpected open Realm found.");
                    realm.close();
                }
            }
            Log.d(TAG, "Incrementing Activity Count [0]: opening Realm.");
            realm = Realm.getDefaultInstance();
        }
        activityCount++;
        Log.d(TAG, "Increment: Count [" + activityCount + "]");
    }

    public static void decrementCount() {
        activityCount--;
        Log.d(TAG, "Decrement: Count [" + activityCount + "]");
        if(activityCount <= 0) {
            Log.d(TAG, "Decrementing Activity Count: closing Realm.");
            activityCount = 0;
            realm.close();
            if(Realm.compactRealm(realmConfiguration)) {
                Log.d(TAG, "Realm compacted successfully.");
            }
            realm = null;
        }
    }
}

And for background thread:

try(Realm realm = Realm.getDefaultInstance()) {
   // ...
}

Upvotes: 4

Jefferson Tavares
Jefferson Tavares

Reputation: 991

Why don't you create a wrapping class for your realm instance (may be a singleton) and then add a few methods to it, so that instead of closing realm each time you can just call your own method and close the used instance as soon as you're finished? Something like this.

public class WrappingRealm {
    public static WrappingRealm getInstance() {
        //create your singleton here. Be aware of synchronization issues
    }

    private Realm getRealm() {
        return Realm.getDefaultInstance();
    }

    public void save(RealmModel obj)  {
        Realm currentRealm = getRealm();

        currentRealm.executeTransaction {
            //Do your stuff
        }

        currentRealm.close();
    }
}

Upvotes: 0

Related Questions