境界与RxJava2可流动的不正确的线程
问题描述:
我想了解如何与Realm
和RxJava2
一起工作(用于异步交易),并做了与交易一些样本项目:境界与RxJava2可流动的不正确的线程
private void writeAllUsers() {
Realm.getDefaultInstance().executeTransactionAsync(realm -> realm.copyToRealmOrUpdate(users));
}
private void getAllUsers() {
getUsers().observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
.subscribe(this::successGetUser, this::handleUserError);
}
private Flowable<RealmResults<User>> getUsers() {
return Realm.getDefaultInstance()
.where(User.class)
.findAllAsync()
.asFlowable();
}
但是当我打电话getAllUsers
,我得到异常:
java.lang.IllegalStateException:从不正确的线程访问域。 领域对象只能在创建它们的线程上访问。
我在这种情况下做错了什么?
答
RealmResults<T>
表示代理视图的线程本地集合,由于Realm的MVCC体系结构,它们绑定到当前线程本地版本的数据库。
这意味着管理的RealmResults或Realm或RealmObject 不能在线程之间传递。
所以你也不应该这样做有RealmResults:
getUsers()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
传球管理结果从io
到main thread
是不行的!
asFlowable
只是包装的RealmChangeListener(仅适用于环线有效)为可流动的,所以线程限制仍然是一个事。
事实上,它永远不会终止,你应该确保你退订。
所以,为了隐藏结果为可流动的这样一种方式,它适用于任何线索,假设你不这样做线程跳吧:
private Flowable<RealmResults<User>> getUsers(Realm realm) {
if(realm.isAutoRefresh()) {
return realm
.where(User.class)
.findAllAsync()
.asFlowable()
.filter(RealmResults::isLoaded);
} else {
return Flowable.just(realm
.where(User.class)
.findAll());
}
}
在读的背景弯针线并通过非托管结果使用copyFromRealm()
更改有点棘手,您不应该在UI线程的RealmResults上使用copyFromRealm()
。
每个'getInstance()'调用都应该有一个匹配的'close()'调用,但只有当Realm或其任何结果不再被访问时。 – EpicPandaForce