2015-02-05 12 views
5

Ich spiele mit RXJava, Nachrüstung in Android. Ich versuche, das zu erreichen, folgende:RxJava + Retrofit, erhalten Sie eine Liste und fügen Sie zusätzliche Informationen für jeden Artikel

ich einen Anruf regelmäßig abzufragen müssen, die mir eine beobachtbare geben> (Von hier aus konnte ich es tat)

Sobald ich diese Liste erhalte ich in jeder Lieferung iterieren wollen und rufen Sie eine andere Methoden, die mir die ETA geben (so nur mehr Info) Ich möchte diese neue Info in die Lieferung anhängen und geben Sie die vollständige Liste mit den zusätzlichen Informationen zu jedem Artikel.

Ich weiß, wie man das ohne rxjava macht, sobald ich die Liste bekomme, aber ich würde gerne üben.

Dies ist mein Code so weit:

pollDeliveries = Observable.interval(POLLING_INTERVAL, TimeUnit.SECONDS, Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)) 
      .map(tick -> RestClient.getInstance().getApiService().getDeliveries()) 
        .doOnError(err -> Log.e("MPB", "Error retrieving messages" + err)) 
        .retry() 
        .subscribe(deliveries -> { 
         MainApp.getEventBus().postSticky(deliveries); 
        }); 

Dies wird mir eine Liste der Lieferungen geben. Jetzt möchte ich den zweiten Teil erreichen.

Hoffe, ich war genug klar. Dank

+0

Nicht sicher, aber Sie könnten in der Lage sein flatmap zu verwenden, um die Lieferungen in eine neue beobachtbaren enthält ETA http zu transformieren://reactivex.io/documentation/operators/flatmap.html – cYrixmorten

+0

Ja, ich habe ein paar Beispiele gesehen, aber ich konnte nicht wirklich verstehen, wie es geht ... es ist das erste Mal, dass ich rxjava benutze – Marcel

+0

Hier ist ein Beispiel, das sich anmeldet GPS-Ort, dann Transformation in Adresssuche Observable https://github.com/mcharmas/Android-ReactiveLocation/blob/master/sample/src/main/java/pl/charmas/android/reactivocation/sample/MainActivity.java Zeile 90 – cYrixmorten

Antwort

4

Schließlich finde ich eine nette Art und Weise, es zu tun.

private void startPolling() { 
    pollDeliveries = Observable.interval(POLLING_INTERVAL, TimeUnit.SECONDS, Schedulers.from(AsyncTask.THREAD_POOL_EXECUTOR)) 
      .flatMap(tick -> getDeliveriesObs()) 
      .doOnError(err -> Log.e("MPB", "Error retrieving messages" + err)) 
      .retry() 
      .subscribe(this::parseDeliveries, Throwable::printStackTrace); 
} 

private Observable<List<Delivery>> getDeliveriesObs() { 
    return RestClient.getInstance().getApiService().getDeliveries() 
      .flatMap(Observable::from) 
      .flatMap(this::getETAForDelivery) 
      .toSortedList((d1, d2) -> { 
       if (d1.getEta() == null) { 
        return -1; 
       } 
       if (d2.getEta() == null) { 
        return 1; 
       } 
       return d1.getEta().getDuration().getValue() > d2.getEta().getDuration().getValue() ? 1 : -1; 
      }); 
} 

Los geht's Schritt für Schritt.

  1. Zuerst erstellen wir einen beobachtbaren, die jede polling_interval Zeit die Methode getDeliveriesObs() auslöst, die die endgültige Liste zurück
  2. Wir Retrofit verwenden, um eine beobachtbare des Anrufs zu bekommen
  3. Wir verwenden flatMap die resut flattern Liste und erhalten Sie in der nächsten Flatmap einen Liefergegenstand, eins nach dem anderen.
  4. Dann erhalten wir die geschätzte Ankunftszeit in das Objekt Lieferung gesetzt und senden Sie
  5. Wir sortieren die Liste nach der voraussichtlichen Ankunftszeit sortiert.
  6. Im Fehlerfall wir drucken und wiederholen, so dass das Intervall nicht
  7. Wir abonnieren schließlich die Liste sortiert und mit ETA innerhalb, dann geben wir es einfach oder was auch immer Sie damit tun müssen.

Es funktioniert richtig und es ist ganz nett, ich beginne rxjava zu mögen :)

+0

Ich mag diese Lösung, und die Schritt für Schritt ist auch nett. –

1

Ich habe nicht viel Zeit mit Java 8 lambdas verbracht, aber hier ist ein Beispiel für die Abbildung jedes Objekts auf ein anderes Objekt, dann ein List<...> Aussteigen am anderen Ende in plain ol‘Java 7:

List<Delivery> deliveries = ...; 
Observable.from(deliveries).flatMap(new Func1<Delivery, Observable<ETA>>() { 
    @Override 
    public Observable<ETA> call(Delivery delivery) { 
     // Convert delivery to ETA... 
     return someEta; 
    } 
}) 
.toList().subscribe(new Action1<List<ETA>>() { 
    @Override 
    public void call(List<ETA> etas) { 

    } 
}); 

Natürlich wäre es nett, die Retrofit-Antwort zu nehmen (vermutlich eine Observable<List<Delivery>>?) Und einfach jeden von denen zu beobachten. Dazu verwenden wir idealerweise etwas wie flatten(), welches doesn't appear to be coming to RxJava anytime soon ist.

Um dies zu tun, können Sie stattdessen etwas tun (viel schöner mit Lambdas). Sie würden Observable.from(deliveries) im obigen Beispiel mit dem folgenden ersetzen:

apiService.getDeliveries().flatMap(new Func1<List<Delivery>, Observable<Delivery>>() { 
    @Override 
    public Observable<Delivery> call(List<Delivery> deliveries) { 
     return Observable.from(deliveries); 
    } 
}).flatMap(...) 
+0

Siehe meine Antwort. Ich benutze deinen Rat, um es zu machen. Vielen Dank @Adam S – Marcel

Verwandte Themen