RxJava / Retrofit呼叫响应中的每个项目

时间:2019-12-28 18:16:52

标签: android retrofit rx-java2

我使用Retrofit / rxJava调用我的API,并且得到可观察的响应,例如 BreedDog

单个列表

。您可以看到我的代码:

compositeDisposable.add(breedDogsDisplayDataRepository.getBreedDogs(name)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableSingleObserver<List<BreedDog>>() {

                @Override
                public void onSuccess(List<BreedDog> breedDogList) {
                    Log.e("test", "okPresenter");
                    view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogList));
                }

                @Override
                public void onError(Throwable e) {
                    Log.e("test", "errorPresenter : " + e.toString());
                    // handle the error case
                    System.out.println(e.toString());
                }
            }));

这有效,但是现在,对于此列表的每个项目,我需要调用我的API以获得URL图像并更新我的列表。 但是我不知道如何...我试图在Observable中更改我的单一响应,并使用了flatMap或flatMapIterate等运算符。等等。但是,我一直都在与Object出错。

这是一个示例:

breedDogsDisplayDataRepository.getBreedDogs(name)
            .flatMapIterable(breedDogs -> breedDogs)
            .map( item ->   breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {

                        @Override
                        public void onSuccess(List<BreedImageResponse> breedImageResponses) {

                        }

                        @Override
                        public void onError(Throwable e) {
                            Log.e("test", "errorPresenter : " + e.toString());
                            // handle the error case
                            System.out.println(e.toString());
                        }
                    })));

我使用好方法吗?还是需要更改某些内容?

2 个答案:

答案 0 :(得分:0)

没有存储库的签名,很难确切地说出问题所在,但是您确实提到getBreedDogs返回了Single<List<BreedDogs>>。在这种情况下,据我所知Single没有flatMapIterable,但是它有flattenAsObservable可用于做您想做的事情。

它将在单身中映射列表,并以可观察的形式发出其项目。这意味着您不再可以使用map,而必须切换到flatMap

.flattenAsObservable(breedDogs -> breedDogs) 
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))
使用

flatMapSingle是因为在这种情况下我们是平面映射Singles

我注意到的另一件事是您的“订阅部分”位于map内,并且您希望将其从中删除。所以理想情况下,您应该像这样向外部移动

.flattenAsObservable(breedDogs -> breedDogs) 
.flatMapSingle(item -> breedDogsDisplayDataRepository.getImageBreedDog(item.getId()))
.subscribeWith(/*...*/);

调度程序由您决定。如果要并行下载图像,建议将其保留在flatMapSingle内。

最后,看来您想收到一个List<BreedImageResponse>,所以我会使用toList()。放在一起:

breedDogsDisplayDataRepository.getBreedDogs(name)
  .flattenAsObservable(breedDogs -> breedDogs) 
  .flatMapSingle(item ->
    breedDogsDisplayDataRepository.getImageBreedDog(item.getId())
      .subscribeOn(Schedulers.io())
  )
  .toList()
  .observeOn(AndroidSchedulers.mainThread())
  .subscribeWith(new DisposableSingleObserver<List<BreedImageResponse>>() {
        @Override
        public void onSuccess(List<BreedImageResponse> breedImageResponses) { 
        }

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

答案 1 :(得分:0)

这是我解决问题的方法:

public Single<List<BreedDogWithImage>> searchDogs(String name) {
    return getBreedDogs(name)
            .flatMapIterable(breedDogs -> breedDogs)
            .flatMap(breedDog -> getImageBreedDogs(breedDog.getId())
                    .flatMapIterable(breedDogWithImages -> breedDogWithImages))
            .toList();
}

所以我可以这样称呼它:

public void searchBreedDogs(String name) {
    compositeDisposable.clear();
    compositeDisposable.add(breedDogsDisplayDataRepository.searchDogs(name)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableSingleObserver<List<BreedDogWithImage>>() {

                @Override
                public void onSuccess(List<BreedDogWithImage> breedDogWithImages) {
                    Log.e("test", "okCall" + breedDogWithImages);
                    view.displayBreedDogs(breedDogToViewModelMapper.map(breedDogWithImages));
                }

                @Override
                public void onError(Throwable e) {
                    Log.e("test", "error ");
                    e.printStackTrace();
                }
            }));
}