带有RxJava2的域可流动的错误线程

时间:2017-10-21 13:02:43

标签: realm rx-java2

我正在尝试了解如何与RealmRxJava2一起工作(对于异步交易)并使用交易做一些示例项目:

 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对象只能在创建它们的线程上访问。

在这种情况下我做错了什么?

1 个答案:

答案 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()