2017-02-16 72 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