2016-02-15 38 views
4

我想在Android中使用RxJava鏈接網絡請求,然後在失敗時重試。我一直在關注如何做到這一點,而不是進入使用vanilla Android和Retrofit自帶的Callback地獄。我能做到這一切的過程中,像這樣的異步任務(以下是我需要做的步驟)登錄。Android/RxJava如何鏈接網絡請求,並在失敗時重試

  1. 登錄用的用戶名/密碼,
  2. 請求SSO令牌如果用戶這種反應是成功的
  3. 呼叫發射服務與SSO令牌

我在AsyncTask其中僅但是,當應用程序在使用SSO令牌到期時簽下的工作一直在做這個,所以我每次看到它過期時都需要提出請求。

爲的AsyncTask的代碼如下所示:

private class LoginUserTask extends AsyncTask<Void, Void, Void> { 
    private final String LOG_TAG = LoginUserTask.class.getSimpleName(); 

    @Override 
    protected Void doInBackground(Void... params) { 
     OkHttpClient httpClient = ((TribeSocial) getApplication()).getHttpClient(); 

     // Login User 
     GroupDockService groupDockLoginService = 
       GroupDockServiceGenerator 
         .createService(GroupDockService.class, 
           httpClient, GroupDockUser.class, new GroupDockUserDeserializer()); 
     GroupDockUser groupDockUser = groupDockLoginService.loginUser("Tribe", username, password); 
     Utility.saveAccountSubdomain(mContext, groupDockUser.getGroupDockSubdomain().getSubdomain()); 

     // Get Sso Token 
     GroupDockService groupDockService = GroupDockServiceGenerator 
       .createService(GroupDockService.class, httpClient); 
     GroupDockSsoResponse ssoResponse = 
       groupDockService.getSsoToken(Utility.getAccountSubdomain(mContext), true); 
     Utility.saveSsoToken(mContext, ssoResponse.getSsoToken()); 

     // Sign in user into Tribe service 
     TribeSocialService tribeSocialLaunchService = 
       TribeServiceGenerator.createService(TribeSocialService.class, 
         httpClient, new LenientGsonConverter(new Gson())); 
     tribeSocialLaunchService.launch(Utility.getSsoToken(mContext)); 

     // Get User id and save it to SharedPreferences 
     TribeSocialService tribeSocialWhoAmIService = 
       TribeServiceGenerator.createService(TribeSocialService.class, httpClient, 
         User.class, new WhoAmIDeserializer()); 
     User tribeUser = tribeSocialWhoAmIService.whoami(); 
     Utility.saveUserId(mContext, tribeUser.getId()); 

     return null; 
    } 

    @Override 
    protected void onPostExecute(Void v) { 
     Utility.launchMainActivity(mContext); 
    } 
} 

我在做與RxJava這項工作嘗試像

GroupDockService groupDockLoginService = 
     GroupDockServiceGenerator 
       .createService(GroupDockService.class, 
         mHttpClient, GroupDockUser.class, new GroupDockUserDeserializer()); 

groupDockLoginService 
     .loginUserRx("Tribe", username, password) 
     .subscribeOn(Schedulers.newThread()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(new Subscriber<GroupDockUser>() { 
      @Override 
      public void onCompleted() { 

      } 

      @Override 
      public void onError(Throwable e) { 
       Log.e(LOG_TAG, "I have errored out: " + e.getMessage()); 
       Toast.makeText(mContext, 
         getString(R.string.username_and_or_password_is_incorrect), 
         Toast.LENGTH_SHORT).show(); 
      } 

      @Override 
      public void onNext(GroupDockUser groupDockUser) { 
       Utility.saveUsernamePassword(mContext, username, password); 
       new LoginUserTask().execute(); 
      } 
     }); 

在該代碼中,我需要做以下

  1. 當loginUserRx成功時,我需要將用戶名和密碼保存到SavedPreferences
  2. 然後,我需要提出網絡請求以獲取sso令牌
  3. 之後,我需要發出第三個也是最終的網絡請求。

現在的代碼只是調用登錄用戶,一旦成功,就會啓動異步任務。理想情況下,我想在這一個請求中將所有請求鏈接在一起。我一直在試驗flatmap,map等,並且無法弄清楚如何在上面列出的過程中鏈接這些呼叫。

任何人都可以對此有所瞭解嗎?謝謝。

+0

如何['retry'(http://reactivex.io/documentation/operators/retry.html)?我不明白地圖或平面地圖如何幫助你做你想要的東西 –

回答

7

看看這個例子。希望,它會激勵你。

service 
     //do login 
     .loginUser() 
     //side effect: save into Shared Preference 
     .doOnNext() 
     //get SSO 
     .flatMap() 
     //do any other side effects 
     .doOnNext() 
     //do final network request 
     .flatMap() 
     //in case of error retry after 5 seconds 
     .retryWhen(observable -> Observable.timer(5, TimeUnit.SECONDS)) 
     .subscribeOn(Schedulers.computation()) 
     .observeOn(AndroidSchedulers.mainThread()) 
     //update you UI 
     .subscribe(); 

Further reading about retry

+0

謝謝。這幫了我很多 –

相關問題