16

I'm using Realm for Android to store some data. When the user presses the log out button, I'd like to clear my entire Realm database. To do that, I have the following snippet of code:

realm.close();
realm.deleteRealmFile(this);
goToLoginActivity();

The issue now is in my onResume function. I'm getting the following exception:

Caused by: java.lang.IllegalStateException: This Realm instance has already been closed, making it unusable.

My onResume code is as follows:

@Override
protected void onResume() {
    super.onResume();

    // I'm trying to check if the realm is closed; this does not work
    if (realm == null) {
        realm = Realm.getInstance(this);
    }

    // Do query using realm
}

How can I check to see if a realm object has been closed already? Alternatively, is there a better way to clear the database than deleting the realm file?

--

Edit: Just saw How can I easily delete all objects in a Realm for iOS. Any word on when the deleteAllObjects API will be available for Android? At the time of writing, Android is at version 0.80.0 and the API is available in iOS in 0.87.0.

Community
  • 1
  • 1
zongweil
  • 2,031
  • 2
  • 21
  • 30

3 Answers3

8

RealmObjects has a isValid() method which will return false if the object has been deleted in the database or the Realm is closed, eg.

Realm realm = Realm.getInstance(getContext());
Foo foo = realm.allObjects(Foo.class).findFirst();
if (foo.isValid()) {
  // Do something with Foo
} else {
  // Any operation will throw a IllegalStateException
}

Delete all

The android API has a Realm.clear(Class clazz) method that does the same thing. http://realm.io/docs/java/api/io/realm/Realm.html#clear-java.lang.Class- This is to mimic the rest of the Collection API's but I can see the confusion in regards to the iOS API.

Christian Melchior
  • 19,978
  • 5
  • 62
  • 53
  • 1
    Thanks for the response. I shouldn't have used the term "realm object" as it looks like it's an overloaded term. I was actually referring to objects of the class Realm. It seems odd to me to have to make a query in order to see if the realm is closed. In regards to Realm.clear, it looks like that only clears all objects of a particular class. In comparison, the deleteAllObjects removes all objects in the Realm database. Is there a better way to get the same behavior than calling Realm.clear on all my possible classes? – zongweil Apr 16 '15 at 22:06
  • Currently no, but if you want to clear the database you can just delete the Realm file instead. Alternatively you would have to call clear() for each model class. – Christian Melchior Apr 18 '15 at 19:49
  • I don't understand, you have a method called `checkIfValid()` in `BaseRealm` that specifies the condition `if (sharedGroupManager != null && !sharedGroupManager.isOpen()) {` for whether the Realm is closed or not; why is this not publicly accessible (protected)? Time for me to go the reflection route as `Realm` is `final`... – EpicPandaForce Oct 07 '15 at 21:37
  • What is the difference between .`isClosed()` and `isValid()`? I have checked `isClosed()` condition however that gives error too. – Hilal Dec 16 '19 at 18:28
4

To check if the realm instance is closed, use Realm's method isClosed:

if(realm.isClosed()) {
    // Do something
}

To delete all Realm objects without deleting the realm file, you can use Realm's method clear; unfortunately you have to pass the RealmObject's class:

Realm realm = Realm.getInstance(context);
realm.beginTransaction();
realm.clear(SomeClass.class);
realm.clear(AnotherClass.class);
realm.commitTransaction();
realm.close();
grim
  • 6,669
  • 11
  • 38
  • 57
1

Instead, do this:

if (realm != null) {
  realm.close();
  realm = null;
}

That way, you don't have to validate if the realm object is closed, but only check if it's null.

TruMan1
  • 33,665
  • 59
  • 184
  • 335