我以这种方式将 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());
}
}
我在应用程序的多个地方使用这个链。例如:
return Observable.merge(
mEventRepository.getAll()
.toObservable(),
subjectNotificationChange
.flatMapMaybe(notification ->
mEventRepository.getAll()
.firstElement()
)
)
问题是我获得了异常:java.lang.IllegalStateException: This Realm instance has already been closed, making it unusable.
我查看了 RealmObservableFactory 的实现方法,每次调用 subscribe 方法都应该创建 Realm 的新实例。整个情况看起来是引用计数的问题。
你知道问题出在哪里吗?
最佳答案
Java 的 try-with-resource
会关闭资源一旦你离开代码块,但是 RxJava 是惰性 等等当您实际订阅时开始工作,这发生在您的代码退出 getAll()
函数之后。
编辑:由于您每次都构建一个特殊的 Realm
实例,将配置传递给它,因此该实例不会共享,因此每次都会最终关闭。
相反,请使用 Realm.setDefaultConfiguration(config)
更早地初始化您的 Realm
。然后,在您的函数中使用 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()
// ...
关于android - Realm 实例已经关闭 - 使用 RxJava2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49086611/