该Realm实例已经关闭,使其无法使用+ RxJava [英] This Realm instance has already been closed, making it unusable + RxJava

查看:183
本文介绍了该Realm实例已经关闭,使其无法使用+ RxJava的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我通过Repository类管理领域实例:

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

并且是此RealmRepository扩展的唯一类,这是我的控制器类. 问题是,当我第一次在片段中执行方法时,我得到了:

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:该Realm实例已经关闭,使其无法使用.

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

但是在此错误之后,如果重新加载片段都可以正常工作.在此第一个片段执行之前,可以执行从Services类调用的方法,并且效果很好. 例如: 即使首先执行此方法,该方法也可以完美运行:

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实例在初始初始化调用之后被计数.每次调用close()都会减少此引用计数,而每次调用getDefaultInstance()都会增加此引用计数.一旦引用计数达到0,就会释放Realm的资源.

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.

考虑到您使用锁定来阻止对Realm实例的访问这一事实,您在进行close()调用时导致引用计数达到0,然后在Realm释放后未重新初始化Realm配置它的资源.

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.

为解决此问题,您需要在后续调用close()之前对getDefaultInstance()的调用进行重叠,以确保在您仍在积极使用Realm的情况下您的引用计数保持> 0,否则,您需要重新初始化每次都会对整个Realm配置进行配置,这会对性能产生影响.

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.

这篇关于该Realm实例已经关闭,使其无法使用+ RxJava的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆