This Realm instance has already been closed, making it unusable + RxJava

孤街醉人 提交于 2019-11-29 22:57:46

问题


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));
}

回答1:


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.




回答2:


The finally method will be executed before the calling method gets the result, in this case.



来源:https://stackoverflow.com/questions/41447871/this-realm-instance-has-already-been-closed-making-it-unusable-rxjava

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!