First of all i manage realm instance by Repository class:
public class RealmRepository {
private Lock lock;
protected RealmRepository() {
lock = new ReentrantLock();
}
public <T> T execute(Executor<T> executor) {
Realm realm = null;
try {
lock.lock();
realm = Realm.getDefaultInstance();
return executor.execute(realm);
} finally {
if (realm != null && !realm.isClosed()) {
realm.close();
}
lock.unlock();
}
}
public interface Executor<T> {
T execute(Realm realm);
}
}
And the only class that extends by this RealmRepository, this is my controller class. Problem is when i do at first time execute method in my fragment i got:
java.lang.IllegalStateException: This Realm instance has already been closed, making it unusable.
But after this error if reload fragment all works fine. And before this first fragment execute method calling from Services classes and works well. For example: This method works perfectly even when execute it first:
public Observable<ModuleRealm> getModule(String moduleTitle) {
return execute(realm -> realm.where(ModuleRealm.class)
.equalTo("code", moduleTitle)
.findAllAsync()
.asObservable()
.first()
.map(RealmResults::first));
}
But this one throws an exception:
public Observable<List<ProductCategoryRealm>> getProductCategories() {
return execute(realm -> realm.where(ProductCategoryRealm.class)
.findAll()
.asObservable()
.first()
.map(realm::copyFromRealm));
}
Realm instances are reference counted after the initial initialization call. Each call to close() decrements this reference count, and each call to getDefaultInstance() will increase this reference count. Realm's resources are freed once the reference count reaches 0.
Considering the fact that you're using a Lock to block accesses to your Realm instance, you're causing reference count to reach 0 when you make your close() call, then not reinitializing the Realm configuration after Realm has already freed its resources.
In order to fix this, you need your calls to getDefaultInstance() to overlap before the subsequent call to close() to ensure that your reference count remains > 0 while you're still actively using Realm, otherwise you need to reinitialize the entire Realm configuration each time which will come with a performance impact.
The finally
method will be executed before the calling method gets the result, in this case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With