2017-08-20 1 views
0

Was ich erreichen möchte, ist, meine Anrufe zu aktualisieren, wo am Ende von allem, wenn ich subskribiere, eine Single und nicht ein zurückgeben Beobachtbar, weil ich immer nur 1 Ergebnis zurückerhalte, aber aufgrund der Art, Aufrufe zu kombinieren, musste ich zu einem Observablen wechseln, um die Observable-Methoden zu nutzen, um Ergebnisse in einem einzigen Ergebnis zusammenzuführen.Vereinfachtes Anrufen von Retrofit2 und Rxjava2, um ein einzelnes anstelle von Observable im Endergebnis zu verwenden

Das Problem, das ich hatte, war herauszufinden, wie man die Ergebnisse von 1 Anruf in einen anderen verwenden und dann dieses Ergebnis mit einem anderen kombinieren und dann eine Kombination von beiden zurückgeben.

Die Reihenfolge meiner Anrufe ist wie folgt:

  1. eine Liste von Logos hochladen
    • Erhalten Sie das Ergebnis des Logos hochladen, die detailliertere Daten der Logos ist ich gerade hochgeladen.
  2. Verwenden Sie die Liste der Ergebnisse, die ich gerade erhalten habe, und verwenden Sie diese in einer neuen Anfrage, die ich mache, um das Buch zu erstellen.
    • Empfang der neu Buchantwort erzeugen, die gerade das Buch ist aber mit mehr automatisch generierten Daten
  3. den aktuellen Autor/user info (ich gezwungen bin, das eine beobachtbare zu machen, weil ein Einzel nicht der Fall ist arbeiten Sie mit dem .zip-Operator)
  4. Verwenden Sie das Autor-Ergebnis und Buchdetails, um ein POJO-Objekt zu erstellen. Gib das als Endergebnis zurück. Gegenwärtig wird dies als beobachtbar zurückgegeben, aber es wird wirklich immer nur 1 Eintrag zurückgegeben, so dass es wenig Sinn macht, ein Observable zurückzugeben. Ich bin nicht sicher, wie ich das umwandeln kann, um eine Single zurückzugeben, also würde ich irgendwelche Vorschläge schätzen.

Dies ist der Code, den ich gerade habe. Die Aufgaben und so sind nur zum Beispiel, aber die Reihenfolge und Anrufe sind genau das, was ich habe:

Retrofit Service:

@GET("/api/Profile/Author") 
Observable<AuthorJson> getAuthor(); 

@POST("/api/Logo") 
Observable<BookLogoJson> uploadBookLogos(@Header("Content-Type") String content_type, @Body RequestBody logo); 

@POST("/api/Book") 
Single<BookDetailsJson> newBook(@Body BookDetailRequest request); 

Die eigentliche Implementierung

List<Book> bookLogos = ...; 

Observable.fromIterable(bookLogos) 
       .subscribeOn(Schedulers.io()) 
       .observeOn(Schedulers.io()) 
       .flatMap(new Function<String, ObservableSource<BookLogoJson>>() { 
        @Override 
        public ObservableSource<BookLogoJson> apply(@NonNull String bookLogos) throws Exception { 
         return mApi.uploadBookLogos(mContentType, getRequestBody(bookLogos, context)); 
        } 
       }).toList().flatMap(new Function<List<BookLogoJson>, SingleSource<BookDetailsJson>>() { 
        @Override 
        public SingleSource<BookDetailsJson> apply(@NonNull List<BookLogoJson> bookLogosRaw) throws Exception { 
         BookDetailRequest request = new BookDetailRequest(); 
         for(BookLogoJson logo : bookLogosRaw){ 
          request.mLogos.add(logo.mId); 
         } 
         return mApi.newBook(request); 
        } 
       }).toObservable().flatMap(new Function<BookDetailsJson, ObservableSource<Book>>() { 
        @Override 
        public ObservableSource<Book> apply(@NonNull BookDetailsJson BookDetailsJson) throws Exception { 
         return Observable.zip(mApi.getAuthor(), 
           Observable.just(BookDetailsJson), 
           new BiFunction<AuthorJson, BookDetailsJson, Book>() { 
            @Override 
            public Book apply(AuthorJson author, BookDetailsJson bookDetails) throws Exception { 
             return mConverter.getBook(author, bookDetails); 
            } 
           }); 
        } 
       }) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribeWith(new Observer<Book>() { 
        @Override 
        public void onSubscribe(@NonNull Disposable d) { 
        } 

        @Override 
        public void onNext(@NonNull Book book) { 
         // Here, I will only ever get 1 Book so an observable makes no sense. 
        } 

        @Override 
        public void onError(@NonNull Throwable e) { 
        } 

        @Override 
        public void onComplete() { 
        } 
       }); 

Antwort

0

Es ist eigentlich ganz einfach, da das Ergebnis aus bereits ein Single ist.

einfach den Anruf zu toObservable() entfernen und die flatMap danach ändern zurückzukehren eine Single:

mApi.getAuthor().firstOrError().map(new Function<AuthorJson, Book>() { 
         public Book apply(@NonNull AuthorJson author) throws Exception { 
     // bookDetails captured by anonymous function 
     return mConverter.getBook(author, bookDetails); 
    } 
}); 

Zusätzlich Retrofit des RxJava Konverter akzeptiert auch Single als Ersatz für Observable. Dies könnte hier zutreffen, da die Anfragen immer ein einzelnes Ergebnis oder einen Fehler ergeben. (Completable kann für No-Response-Anfragen verwendet werden)

+0

Ein Single ist was ich eigentlich verwenden möchte, kann aber nicht wegen .zip. Es ist möglich, dass meine Frage das nicht klarstellte, aber das ist es, was ich versuche, alle meine Anrufe zu erreichen, wird nie mehr als 1 Ergebnis zurückgeben, daher wird Single passender sein. – AndFantasy

+0

Warum ist ein '.Zip "erforderlich? Wenn Sie Ihren Code betrachten, müssen Sie nur ein "Single" und ein bereits berechnetes Objekt zusammenführen, was mit einer einfachen '.map' geschehen kann. – Kiskae

+0

Ich habe eigentlich einen weiteren Anruf, den ich machen muss, bevor ich das Buch zurückschicke. Wie würden Sie Ihren Code ändern, um nach dem Zurückgeben des letzten Buches tatsächlich eine weitere Anfrage zu stellen? Das ist mein Problem - ich muss eine erste Anfrage (1) machen, dieses Anfrageergebnis verwenden, um eine weitere Anfrage zu erstellen (2), und dann dieses Ergebnis von (2) mit einer letzten Anfrage (3) kombinieren, die eine Single zurückgibt Objekt, das Daten von (2) und (3) verwendet. Ich hoffe das erklärt die Situation ein wenig besser. Der Wechsel von (2) zu (3) ist der Grund, warum ich eine .zip benutze – AndFantasy

Verwandte Themen