2017-10-21 52 views
0

我想了解如何与RealmRxJava2一起工作(用于异步交易),并做了与交易一些样本项目:境界与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:从不正确的线程访问域。 领域对象只能在创建它们的线程上访问。

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

+0

每个'getInstance()'调用都应该有一个匹配的'close()'调用,但只有当Realm或其任何结果不再被访问时。 – EpicPandaForce

回答

0

RealmResults<T>表示代理视图的线程本地集合,由于Realm的MVCC体系结构,它们绑定到当前线程本地版本的数据库。

这意味着管理的RealmResults或Realm或RealmObject 不能在线程之间传递。

所以你也不应该这样做有RealmResults:

getUsers() 
.observeOn(AndroidSchedulers.mainThread()) 

.subscribeOn(Schedulers.io()) 

传球管理结果从iomain 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()