Skip to content Skip to sidebar Skip to footer

How To Manage Realm Instance?

I have an Activity that manage multiples fragments and nested fragment, like that : Activity -> RootFragment1 -> NestedFragment1, NestedFragment2              -&

Solution 1:

The docs say that you should open/close Realm in onCreateView()/onDestroyView(), but in my experience the fragment lifecycle is unusually erratic, so I can show you two other approaches.

1.) open/close the Realm in Activity.onCreate() and Activity.onDestroy(), then share it to the fragments (and even down the view hierarchy!) using getSystemService().

publicclassMyActivityextendsAppCompatActivity {
    Realm realm;

    @OverrideprotectedvoidonCreate(Bundle bundle) {
        // ...
        realm = Realm.getDefaultInstance();
    }

    @OverrideprotectedvoidonDestroy() {
        realm.close();
        realm = null;
        // ...
    }

    // -----------------------------privatestatic final StringREALM_TAG = "__REALM__";

    publicstaticRealmgetRealm(Context context) {
        // noinspection ResourceTypereturn (Realm)context.getSystemService(REALM_TAG);
    }

    @OverridepublicObjectgetSystemService(@NonNullString name) {
        if(REALM_TAG.equals(name)) {
            return realm;
        }
        returnsuper.getSystemService(name);
    }
}

Then in fragment you can do

Realmrealm= MyActivity.getRealm(getActivity());

And in views you can do

Realmrealm= MyActivity.getRealm(getContext());

2.) manage the Realm lifecycle globally for the UI thread using retained fragment as lifecycle listener / activity reference counter.

/**
 * Created by Zhuinden on 2016.08.16..
 */publicclassRealmManager {
    privatestatic final StringTAG = "RealmManager";

    staticRealm realm;

    staticRealmConfiguration realmConfiguration;

    publicstaticvoidinit(Context context) {
        Realm.init(context);
    }

    publicstaticvoidinitializeRealmConfig(Context appContext) {
        if(realmConfiguration == null) {
            Log.d(TAG, "Initializing Realm configuration.");
            setRealmConfiguration(newRealmConfiguration.Builder(appContext).initialData(newRealmInitialData())
                    .deleteRealmIfMigrationNeeded()
                    .inMemory()
                    .build());
        }
    }

    publicstaticvoidsetRealmConfiguration(RealmConfiguration realmConfiguration) {
        RealmManager.realmConfiguration = realmConfiguration;
        Realm.setDefaultConfiguration(realmConfiguration);
    }

    privatestatic int activityCount = 0;

    publicstaticRealmgetRealm() { // use on UI thread only!return realm;
    }

    publicstaticvoidincrementCount() {
        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 + "]");
    }

    publicstaticvoiddecrementCount() {
        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;
        }
    }
}

In conjunction with

publicclassRealmScopeListenerextendsFragment {
    publicRealmScopeListener() {
        setRetainInstance(true);
        RealmManager.incrementCount();
    }

    @OverridepublicvoidonDestroy() {
        RealmManager.decrementCount();
        super.onDestroy();
    }
}

And

/**
 * Created by Zhuinden on 2016.09.04..
 */publicclassRealmActivityextendsAppCompatActivity {
    protected Realm realm;

    @OverrideprotectedvoidonCreate(@Nullable Bundle savedInstanceState) {
        RealmManager.init(this);
        RealmManager.initializeRealmConfig(getApplicationContext());

        super.onCreate(savedInstanceState);
        RealmScopeListenerrealmScopeListener= (RealmScopeListener)getSupportFragmentManager().findFragmentByTag("SCOPE_LISTENER");
        if(realmScopeListener == null) {
            realmScopeListener = newRealmScopeListener();
            getSupportFragmentManager().beginTransaction().add(realmScopeListener, "SCOPE_LISTENER").commit();
        }
        realm = RealmManager.getRealm();
    }
}

This allows you to call RealmManager.getRealm()for the UI thread, and its lifecycle is managed by retain fragments.

Post a Comment for "How To Manage Realm Instance?"