2016-02-15 41 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

谢谢。这帮了我很多 –

相关问题