2017-10-09 5 views
0

J'ai seulement ceci:Comment se rendre à Observable avec Liste d'objets de Realm utilisant RxJava?

public Observable<List<Movie>> getAll() { 
    return Observable.just(Movie.class) 
      .flatMap(t -> Observable.just(t) 
        .doOnSubscribe(disposable -> realm.executeTransaction(realm1 -> realm1.where(Movie.class).findAll())) 
        .onErrorResumeNext((ObservableSource<? extends Class<Movie>>) observer -> Observable.empty()) 
        .map(all -> realm.where(Movie.class).findAll()) 
      ); 
} 

Mais il semble vraiment laid))

Tout serait bien, si là où les possibilités d'éviter la duplication de code et enregistrer realm.where (Movie.class) .findAll() et réutiliser dans map(). La méthode RealmResults addAll est obsolète.

+1

Je pense que vous devriez lire [ce] (https://academy.realm.io/posts/creating-a-reactive-data-layer-with-realm-and-rxjava2/) et aussi vérifier [ this] (https://stackoverflow.com/a/44341905/6774854) réponse. – masp

+0

Je ne pense pas que ça marchera, parce que Observable.empty va juste émettre onComplete. Donc, vous obtiendrez une observable qui se termine. –

+0

@masp merci de lier ma réponse, malheureusement la question posée là-bas juste abandonné sa question, donc je ne peux pas marquer cela comme doublon. Triste vie... – EpicPandaForce

Répondre

0

Comme décrit également here:

private io.reactivex.Flowable<List<Movie>> getAll() { 
    return io.reactivex.Flowable.create(new FlowableOnSubscribe<List<Movie>>() { 
     @Override 
     public void subscribe(FlowableEmitter<List<Movie>> emitter) 
       throws Exception { 
      Realm realm = Realm.getDefaultInstance(); 
      RealmResults<Movie> results = realm.where(Movie.class).findAllAsync(); 
      final RealmChangeListener<RealmResults<Movie>> listener = _realm -> { 
       if(!emitter.isUnsubscribed() && results.isLoaded()) { 
        emitter.onNext(results); 
       } 
      }; 
      emitter.setDisposable(Disposables.fromRunnable(() -> { 
       results.removeChangeListener(listener); 
       realm.close(); 
      })); 
      results.addChangeListener(listener); 
     } 
    }, BackpressureStrategy.LATEST) 
    .subscribeOn(AndroidSchedulers.mainThread()) 
    .unsubscribeOn(AndroidSchedulers.mainThread()); 

Mais comme @masp dit un commentaire, vous pouvez en savoir plus sur la conception d'une couche de données réactive en utilisant Realm avec RxJava2 en my article about this on realm.io that was published a month ago.

Donc, avec Realm 4.0.0-RC1 et au-dessus, vous pouvez en fait juste faire

private io.reactivex.Flowable<List<Movie>> getAll(Realm realm) { 
    if(realm.isAutoRefresh()) { 
     return realm.where(Movie.class) 
       .findAllAsync() 
       .asFlowable() 
       .filter(RealmResults::isLoaded); 
    } else { // for background threads 
     return Flowable.just(realm.where(Movie.class).findAll()); 
    } 
} 
0

Vous pouvez toujours extraire le code de trouver film dans une autre méthode pour être réutilisée. Même dans l'API fonctionnelle, nous devrions éviter la rupture DRY.

public void code() { 
    public Observable<List<Movie>> getAll() { 
     return Observable.just(Movie.class) 
       .flatMap(t -> Observable.just(t) 
         .doOnSubscribe(disposable -> realm.executeTransaction(realm1 -> findMovie((Object) realm1))) 
         .onErrorResumeNext((ObservableSource<? extends Class<Movie>>) observer -> Observable.empty()) 
         .map(all -> findMovie((Object) all)) 
       ); 
    } 

} 

private Object findMovie(Object realm1) { 
    return realm1.where(Movie.class).findAll(); 
}