2015-02-05 2 views
5

Я играю с RXJava, модифицированный в Android. Я пытаюсь выполнить следующие действия:RxJava + модифицируйте, получите список и добавьте дополнительную информацию по каждому товару

Мне нужно периодически опрашивать вызов, который даст мне Наблюдаемые> (От здесь я мог бы это сделал)

После того, как я получаю этот список, я хочу итерацию в каждой поставке и вызовите другие методы, которые дадут мне ETA (так что просто больше информации). Я хочу прикрепить эту новую информацию к доставке и вернуть полный список с дополнительной информацией, прикрепленной к каждому элементу.

Я знаю, как это сделать без rxjava, как только я получу список, но я бы хотел попрактиковаться.

Это мой код до сих пор:

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

Это дает мне список поставок. Теперь я хотел бы выполнить вторую часть.

Надеюсь, я был достаточно ясен. Благодаря

+0

Не уверен, но вы можете быть в состоянии использовать flatmap превратить поставки в новом наблюдаемый, содержащих ЭТОТ HTTP://reactivex.io/documentation/operators/flatmap.html – cYrixmorten

+0

Да, я видел несколько примеров, но я не мог понять, как это сделать ... это первый раз, когда я пытаюсь использовать rxjava – Marcel

+0

Вот пример подписки на GPS, затем преобразование в поиск адреса. Наблюдаемый https://github.com/mcharmas/Android-ReactiveLocation/blob/master/sample/src/main/java/pl/charmas/android/reactivelocation/sample/MainActivity.java line 90 – cYrixmorten

ответ

4

Наконец-то я нашел хороший способ сделать это.

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

Пошли шаг за шагом.

  1. Сначала мы создаем наблюдаемые, который запускает каждый POLLING_INTERVAL раз, когда метод getDeliveriesObs(), который будет возвращать окончательный список
  2. Мы используем переоснащение, чтобы получить наблюдаемый вызов
  3. Мы используем flatMap для flattern в resut и перейдите в следующую планку «Поставка», один за другим.
  4. Затем мы получаем расчетное время прибытия, установленное внутри объекта доставки, и возвращаем его
  5. Мы сортируем список по заказу в примерное время прибытия.
  6. В случае ошибки мы печатаем и повторяем так, чтобы интервал не останавливался
  7. Мы подписываемся, наконец, чтобы отсортировать список и с помощью ETA внутри, а затем просто вернуть его или что-то еще, что вам нужно сделать.

Это работает нормально, и это очень приятно, я начинаю как rxjava :)

+0

Мне нравится это решение, и шаг за шагом тоже приятно. –

1

Я не проводил много времени с Java 8 лямбды, но вот пример отображения каждого объекта на другой объект, а затем получить List<...> на другом конце в простом ола»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) { 

    } 
}); 

конечно, было бы неплохо, чтобы принять ответ Дооснащаемый (предположительно Observable<List<Delivery>>?) и просто наблюдать за каждым из них. Для этого мы идеально используем что-то вроде flatten(), которое doesn't appear to be coming to RxJava anytime soon.

Для этого вы можете сделать что-то подобное (гораздо приятнее с лямбдами). Вы бы заменить Observable.from(deliveries) в приведенном выше примере со следующим:

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

См. Мой ответ. Я использую ваш совет, чтобы сделать это. Спасибо @Adam S – Marcel