Realm实例已经关闭 - 使用RxJava2

时间:2018-03-03 16:43:12

标签: android realm rx-java2

我以这种方式将Realm与RxJava一起使用:

public Flowable<List<EventEntity>> getAll() {
  try (final Realm realm = Realm.getInstance(mRealmConfiguration)) {
    RealmQuery<RealmEvent> query = realm.where(RealmEvent.class);
    Flowable<RealmResults<RealmEvent>> result;
    if (realm.isAutoRefresh()) {
       result = query
       .findAllAsync()
       .asFlowable()
       .filter(RealmResults::isLoaded);
    } else {
      result = Flowable.just(query.findAll());
    }
    return result
      .unsubscribeOn(AndroidSchedulers.mainThread());
  }
}

我在app中的多个地方使用此链。例如:

return Observable.merge(
      mEventRepository.getAll()
        .toObservable(),
      subjectNotificationChange
        .flatMapMaybe(notification ->
          mEventRepository.getAll()
            .firstElement()
        )
    )

问题是我获得异常:java.lang.IllegalStateException:此Realm实例已被关闭,使其无法使用。

我查看了RealmObservableFactory的实现方法,每次调用subscribe方法都应该创建Realm的新实例。整个情况看起来与引用计数有关。

你知道哪里有问题吗?

2 个答案:

答案 0 :(得分:1)

Java try-with-resource在您离开代码区后立即关闭资源,但RxJava 懒惰并且全部只在以后开始工作你实际订阅了,这是在你的代码退出getAll()函数后发生的。

编辑:由于每次构建一个特殊的Realm实例,并将配置传递给它,实例不会被共享,因此每次都会关闭。

相反,请先使用Realm初始化您的Realm.setDefaultConfiguration(config)。然后,在您的函数中使用Realm.getDefaultInstance(),这样您就可以访问默认的共享实例,而不是每次都创建一个新实例。

Edit2:最简单的解决方案是保留对Realm实例的引用:

class MyRepository {

    private final Realm realm;

    public MyRepository(Realm realm) {
        this.realm = realm;
    }

    public Flowable<List<EventEntity>> getAll() {
        RealmQuery<RealmEvent> query = realm.where(RealmEvent.class);
        // ...
    }

}

Realm realm = Realm.getDefaultInstance();
MyRepository repository = MyRepository(realm);
repository.getAll()
// ...

答案 1 :(得分:0)

我找到解决方案。在官方示例中错误。当您调用提到的链时,必须存在同一线程的其他打开的Realm实例。在其他情况下,RealmResult无效。可以使用 ESala 提到的解决方案。