2017-02-16 66 views
2

我有2个改型呼叫我需要做出& B:RxJava flatMapIterable与concatMap

(A):返回一个ArrayList

(B):得到的结果(A),它是一个ArrayList 。 (B)遍历ArrayList并使用每个ArrayList进行翻新调用,并将生成的数据组合到最终ArrayList中,该ArrayList发送给我的订阅者onNext()

我能够使用flatmap工作,但解决方案是不是很优雅。据我了解,更好的解决方案将是使用flatMapIterable与concatMap,但我似乎无法采用我已经用flatatIterable与concatMap工作。

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()) 
       .flatMap(new Func1<UserSelfFollows, Observable<? extends ArrayList<Media.MediaData>>>() { 
        @Override 
        public Observable<? extends ArrayList<Media.MediaData>> call(UserSelfFollows userSelfFollows) { 

         //make second requests based on response from First request to get all Users 
         ArrayList<Media.MediaData> arAllMedia = new ArrayList<>(); 
         for(UserSelfFollows.UserDataFollows user : userSelfFollows.userdata){ 

          Response <ResponseBody> response ; 
          Call <ResponseBody> call; 
          try { 
           call = ServiceFactory.createRetrofitService().getMediaOfUser(user.id,sessionMgr.getAuthToken()); 
           response = call.execute(); 
          }catch(IOException ex){ 
           return Observable.error(ex); 
          } 

          if (response.isSuccessful()) { 

           try { 
            String str = responseHelper.streamToString(response.body().byteStream()); 
            Gson gson = new GsonBuilder().create(); 
            Media media = gson.fromJson(str, Media.class); 

            arAllMedia.addAll(media.mediaData); 

           } catch (IOException e) { 
            return Observable.error(e); 
           } 
          } else { 
           return Observable.error(new Exception( responseHelper.getErrorString(response.errorBody().byteStream()))); 
          } 
         } 
         return Observable.just(arAllMedia); 

        } 
       }) 
       .subscribeOn(Schedulers.newThread()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new Subscriber<ArrayList<Media.MediaData>>() { 
        @Override 
        public final void onCompleted() { 

        } 

        @Override 
        public final void onError(Throwable e) { 

        } 

        @Override 
        public final void onNext(ArrayList<Media.MediaData> arMedia) { 

        } 
       }) 

这里是我到目前为止,但它不会编译:

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()) 
      .flatMapIterable(new Func1<UserSelfFollows, Iterable<?>>() { 
       @Override 
       public Iterable<?> call(UserSelfFollows userSelfFollows) { 
        return userSelfFollows.userdata; 
       } 
      }) 
      .<Media.MediaData>flatMap(new Func1<UserSelfFollows.UserDataFollows, Observable<Media.MediaData>>() { 
       @Override 
       public Observable<Media.MediaData> call(UserSelfFollows.UserDataFollows user) { 
        return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken()); 
       } 
      }) 
      .toList(); 

的错误是:

enter image description here

回答

1

我从来没有使用过这两种flatMapIterableconcatMap,但作为替代解决方案,您可以使用flatMapcompose运营商:

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()) 
    .flatMap(list -> Observable.from(list)) 
    .compose(getComposer()) 
    .subscribe(mediaData -> mMediaDataList.add(mediaData), throwable -> {},() -> { // on complete do something with mMediaList}); 

getComposer()返回一个变压器UserSelfFollows - 如果我理解正确的情况下,你可以使用flatMapIterable>Media.MediaData

protected Observable.Transformer<UserSelfFollows, Media.MediaData> getComposer() { 
    return ; 
} 
+0

没有兰巴是一样的。在操作员内使用新的。 AndroidStudio会建议执行什么 – Blackbelt

+0

但您只需更换lambda,对吧? – Blackbelt

1

,然后flatMap运营商,在最后收集所有的改装调用导致与toList
在第一flatMapIterable你消光的UserDataFollows列表你从名单发出的多个项目的第一个电话(getUserFollowing())到Obsevrable得到,然后flatMap创建一个Observable,使改造呼吁每个UserSelfFollows.UserDataFollows数据对象(它会发生在平行其中在这里似乎更适合,但你也可以使用concatMap,如果你有兴趣顺序执行),然后收集所有最终数据一起,作为MediaData对象的列表,你可以使用toList

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()) 
      .flatMapIterable(new Func1<UserSelfFollows, Iterable<?>>() { 
       @Override 
       public Iterable<?> call(UserSelfFollows userSelfFollows) { 
        return userSelfFollows.userdata; 
       } 
      }) 
      .flatMap(new Func1<UserSelfFollows, Observable<Media>>() { 
       @Override 
       public Observable<Media> call(UserSelfFollows user) { 
        return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken()); 
       } 
      }) 
      .toList() 
      .subscribe(new Action1<List<Media>>() { 
       @Override 
       public void call(List<Media> rs) { 
        //do something with the list of media data 
       } 
      }); 
+0

此行不包含:return ServiceFactory.createRetrofitService()。getMediaOfUser(user.id,sessionMgr.getAuthToken());没有'user'的属性'id'.....我已经用你的代码更新了我的问题并抛出了错误。 – Mike6679

+0

你的代码基本上抛出了我用我的代码 – Mike6679

+0

得到的同样的错误,要从你提供的代码片段中解决像这样的编译问题是相当困难的,我不确定你的方法返回的确切类型是什么,无论如何,如果您遇到困难,您可以让自动完成功能执行flatMap工作,并且它会向您建议您预期的正确类型。 – yosriz

0

Yosriz的回答让我走向了正确的方向。所以为了避免别人用这个拉出来,这里是全码解决方案:这里是全码解决方案:

ServiceFactory.createRetrofitService().getUserFollowing(sessionMgr.getAuthToken()) 
       .flatMapIterable(new Func1<UserSelfFollows, Iterable<UserSelfFollows.UserDataFollows>>() { 
        @Override 
        public Iterable<UserSelfFollows.UserDataFollows> call(UserSelfFollows userSelfFollows) { 
         return userSelfFollows.userdata; 
        } 
       }) 
       .flatMap(new Func1<UserSelfFollows.UserDataFollows, Observable<Media>>() { 
        @Override 
        public Observable<Media> call(UserSelfFollows.UserDataFollows user) { 
         return ServiceFactory.createRetrofitService().getMediaOfUser(user.id, sessionMgr.getAuthToken()); 
        } 
       }) 
       .toList() 
       .subscribeOn(Schedulers.newThread()) 
       .observeOn(AndroidSchedulers.mainThread()) 
       .subscribe(new Subscriber<List<Media>>() { 
        @Override 
        public final void onCompleted() { 

        } 

        @Override 
        public final void onError(Throwable e) { 

         userMessageHandler.showDialog(mParentActivity, mParentActivity.getString(R.string.error_retrieving_data_title), 
           mParentActivity.getString(R.string.error_self_following_media) + e.getMessage(), 0); 
        } 

        @Override 
        public final void onNext(List<Media> arMedia) { 

         if (arMedia.size() == 0) 
          userMessageHandler.showToast(mParentActivity, mParentActivity.getString(R.string.warn_no_following)); 
         else { 

          ArrayList<Media.MediaData> allMedia = new ArrayList<>(); 
          for(Media media : arMedia){ 
           allMedia.addAll(media.mediaData); 
          } 
          mBinding.gridview.setAdapter(new MediaGridViewAdapter(mParentActivity,FollowingViewModel.this, allMedia)); 
         } 
        } 
       }); 
+0

太棒了!如果这有帮助,请接受我的回答:) – yosriz