【问题标题】:RxJava / Retrofit Call for every item in a reponse响应中每个项目的 RxJava / Retrofit 调用
【发布时间】:2020-04-18 04:26:27
【问题描述】:

我用 retrofit/rxJava 调用我的 API,我得到一个 Observable 响应,例如 BreedDogSingle List

。你可以看看我的代码:

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 图像并更新我的列表.. 但我不知道怎么...

这是一个例子:

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

我使用好方法吗?还是需要改变一些东西?

【问题讨论】:

    标签: android retrofit rx-java2


    【解决方案1】:

    这是我解决问题的方法:

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

    【讨论】:

      【解决方案2】:

      如果没有存储库的签名,很难确切地说出了什么问题,但您确实提到getBreedDogs 返回一个Single&lt;List&lt;BreedDogs&gt;&gt;。如果是这种情况,据我所知,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&lt;BreedImageResponse&gt;,所以我会使用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) {}
        });
      

      【讨论】:

      • 感谢您的帮助。我找到了一个看起来像你的答案的解决方案。我把我的代码放在下面
      猜你喜欢
      • 1970-01-01
      • 2016-05-08
      • 2015-06-26
      • 2017-01-19
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 2016-10-28
      • 1970-01-01
      相关资源
      最近更新 更多