我以这种方式将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的新实例。整个情况看起来与引用计数有关。
你知道哪里有问题吗?
答案 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 提到的解决方案。