2017-10-21 65 views
0

Je suis en train de comprendre comment travailler avec Realm et RxJava2 ensemble (pour les transactions async) et fait quelques exemple de projet avec des transactions:Royaume avec RxJava2 Flowable fil incorrect

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(); 
    } 

Mais quand je l'appelle getAllUsers, je reçois exception :

java.lang.IllegalStateException: Accès au domaine à partir d'un thread incorrect. Les objets de domaine ne sont accessibles que sur le thread dans lequel ils ont été créés.

Qu'est-ce que j'ai fait de mal dans ce cas?

+0

Chaque appel 'getInstance()' devrait avoir un appel 'close()' correspondant, mais uniquement lorsque le domaine ou l'un de ses résultats ne sera plus accessible. – EpicPandaForce

Répondre

0

RealmResults<T> représente une collection locale de threads de vues proxy, où, en raison de l'architecture MVCC de Realm, ils sont liés à la version locale locale de la base de données.

Cela signifie qu'un RealmResults géré ou Realm ou RealmObject ne peut pas être transmis entre les threads.

Vous ne pouvez pas et ne doit pas faire cela avec un RealmResults:

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

.subscribeOn(Schedulers.io()) 

Passing géré résultats io-main thread est non-non!


asFlowable juste enveloppe le RealmChangeListener (valable uniquement sur les fils de boucleur) en tant que fluide, de sorte que le confinement de fil est encore une chose. En fait, il ne se terminera jamais, et vous devriez vous assurer de vous désabonner.

Donc, pour cacher les résultats que Flowable de telle manière que cela fonctionne sur un fil, en supposant que vous ne faites fil saute avec elle:

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()); 
    } 
} 

lecture sur un fil de boucleur de fond et passer des résultats non gérés sur changer en utilisant copyFromRealm() est légèrement plus délicat, vous ne devriez pas utiliser copyFromRealm() sur un RealmResults sur un thread d'interface utilisateur.