2017-10-21 71 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()