我正在尝试了解如何与Realm
和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:从错误的线程访问Realm。 Realm对象只能在创建它们的线程上访问。
在这种情况下我做错了什么?
答案 0 :(得分:0)
RealmResults<T>
表示代理视图的线程局部集合,由于Realm的MVCC架构,它们被绑定到数据库的当前线程本地版本。
这意味着托管的RealmResults或Realm或RealmObject 不能在线程之间传递。
所以你不能也不能用RealmResults做到这一点:
getUsers()
.observeOn(AndroidSchedulers.mainThread())
.subscribeOn(Schedulers.io())
将管理结果从io
传递到main thread
是禁忌!
asFlowable
只是将RealmChangeListener(仅在looper线程上有效)包装为Flowable,因此线程限制仍然是一个问题。
事实上,它永远不会终止,你应该确保取消订阅。
所以要将结果隐藏为Flowable,使其适用于任何线程,假设你不用它进行线程跳转:
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()
。