2016-11-04 6 views
2

Ich muss mehrere API-Aufrufe concat und ich möchte retrofit2 und rxJava Observablen verwenden, um dies zu tun. Mein Szenario ist wie folgt:Concat mehrere Anrufe mit Retrofit 2 und rxJava

Ich muß einen ersten Anruf tun, die ein Array von Objekten zurück, wird die Antwort so etwas wie:

[{"title": "Title 1", "id": "1"}, {"title": "Title 2", "id": "2"}] 

Dann brauche ich pro jedes Objekt einen API-Aufruf zu tun, so dass jedes API-Antwort des Objekts wird so etwas wie:

[{"title": "Chapter A", "id": "1A", ...}, {"title": "Chapter B", "id": "1B", ...}, ...] 

Deshalb möchte ich all diese Anrufe verketten und es in einem einzigartigen Response-Objekt verschmelzen, die alle Informationen haben würden. Wie könnte ich das tun? Wie kann ich den ersten Anruf tätigen, dann mit der Antwort einen Anruf pro Objekt machen und warten bis alle Anrufe erledigt sind und die Ergebnisse zusammenführen?

Vielen Dank

+2

Verwendung zip oder combileLast von RxJava – Blackbelt

+0

Vielen Dank, aber wie könnte ich das tun? Ich meine, wie kann ich das Ergebnis des ersten Observablen erhalten und dann die anderen Observablen erstellen und seine Ergebnisse kombinieren? Ich nehme an, dass com zip verwendet wird, sobald ich die Liste der Observablen habe, aber wie kann ich den ersten Aufruf durchführen, die Antwort analysieren, um die Liste der Observablen zu erstellen? – FVod

Antwort

5

Sie Objekte mit definierten Eigenschaften haben Angenommen:

public class TvShow { 
    public String title; 
    public Long id; 
    public List<TvChapter> chapterList; 
} 

public class TvChapter { 
    public String title; 
    public String id; 
} 

Und Sie haben bereits Methoden, um Daten zu erhalten:

public Observable<List<TvShow>> getShows() 

public Observable<List<TvChapter>> getTvChapters(Long tvShowId) 

Hier ist die kombinierte RxJava Strom, dass die Renditen Observable<List<TvShow>>:

getShows() 
     .flatMap(new Func1<List<TvShow>, Observable<TvShow>>() { 
      @Override 
      public Observable<TvShow> call(List<TvShow> tvShows) { 
       return Observable.from(tvShows); 
      } 
     }).flatMap(new Func1<TvShow, Observable<TvShow>>() { 
    @Override 
    public Observable<TvShow> call(TvShow tvShow) { 
     return Observable.zip(Observable.just(tvShow), 
       getTvChapters(tvShow.id), 
       new Func2<TvShow, List<TvChapter>, TvShow>() { 
        @Override 
        public TvShow call(TvShow tvShow, List<TvChapter> tvChapters) { 
         tvShow.chapterList = tvChapters; 
         return tvShow; 
        } 
       }); 
    } 
}).toList(); 

Die Idee ist:

  1. alle Shows Fetch (getShows)
  2. einen Strom von einzelnen Shows aus der Liste Get (Observable.from() Operator)
  3. Get Kapitel für jede Show (getTvChapters(tvShow.id))
  4. Combine Ergebnisse der tvChapters Anruf mit tvShow
  5. Merge alle Ergebnisse (Observable.toList() Operator)
+0

Vielen Dank, es funktioniert wie ein Charme – FVod

1

mit lambda

getTitlesList() //first API call that returns Observable<Titles> 
     .flatmap(titles -> Observable.from(titles)) //forcing list to emit each element separately 
     .flatmap(title -> getDetail(title)) //second API call that returns Observable<Detail> 
     .toList() //collect all emitted items to list 
     .subscribeOn(Schedulers.io()) // don't forget to apply async scheduler, 
            // otherwise you'll get *android.os.NetworkOnMainThreadException* 
     .observeOn(AndroidSchedulers.mainThread()) //and switch thread back to main, if needed 
     .subscribe(details -> { 
      //process your details list 
     }, e -> { 
      //error handling 
     }); 
+0

Hey @MaximOstrovidov was meinst du mit: async Scheduler. Ich bin wirklich verwirrt und ich bekomme diese Ausnahme! –

+0

Hallo, ich habe meine Antwort aktualisiert –

+0

Ich habe wirklich mit diesem Problem zu kämpfen. Ich habe bereits einige Leute, die mir helfen, aber keine der Antworten hat funktioniert. Kannst du bitte den Thread überprüfen? Ich werde wirklich dankbar sein! (Ich weiß nicht, ob ich das tun könnte, aber ich weiß nicht, wie ich dich dort hin beschwören könnte) http://stackoverflow.com/questions/44007570/rxjava-2-retrofit-2-networkonmainthreadexception/44010393#44010393 –

Verwandte Themen