Android/RxJava如何链接网络请求并在失败时重试

Android/RxJava如何链接网络请求并在失败时重试,java,android,retrofit,rx-android,Java,Android,Retrofit,Rx Android,我试图在Android中使用RxJava链接网络请求,然后在失败时重试。我一直在研究StackOverflow如何做到这一点,而不至于陷入使用vanilla Android和改型带来的回调地狱。我可以在一个过程中完成这一切,在像这样的异步任务中(下面是我需要执行的步骤)登录 使用用户名/密码登录用户 如果响应成功,则请求SSO令牌 使用该sso令牌调用启动服务 我一直在一个AsyncTask中做这件事,它只在登录时起作用。但是,SSO令牌在应用程序使用时过期,因此每次看到它过期时,我都需要发出请

我试图在Android中使用RxJava链接网络请求,然后在失败时重试。我一直在研究StackOverflow如何做到这一点,而不至于陷入使用vanilla Android和改型带来的回调地狱。我可以在一个过程中完成这一切,在像这样的异步任务中(下面是我需要执行的步骤)登录

  • 使用用户名/密码登录用户
  • 如果响应成功,则请求SSO令牌
  • 使用该sso令牌调用启动服务
  • 我一直在一个
    AsyncTask
    中做这件事,它只在登录时起作用。但是,SSO令牌在应用程序使用时过期,因此每次看到它过期时,我都需要发出请求

    AsyncTask的代码如下所示:

    私有类LoginUserTask扩展异步任务{
    私有最终字符串LOG_TAG=LoginUserTask.class.getSimpleName();
    @凌驾
    受保护的Void doInBackground(Void…参数){
    OkHttpClient httpClient=((TribeSocial)getApplication()).getHttpClient();
    //登录用户
    GroupDockService groupDockLoginService=
    GroupDockServiceGenerator
    .createService(GroupDockService.class,
    httpClient,GroupDockUser.class,新的GroupDockUserDeserializer());
    GroupDockUser-GroupDockUser=groupDockLoginService.logiuser(“部落”,用户名,密码);
    实用工具.saveAccountSubdomain(mContext,groupDockUser.getGroupDockSubdomain().getSubdomain());
    //获取Sso令牌
    GroupDockService GroupDockService=GroupDockService生成器
    .createService(GroupDockService.class,httpClient);
    组docksorresponse-ssorresponse=
    groupDockService.getSsoToken(Utility.getAccountSubdomain(mContext),true);
    saveSsoToken(mContext,ssoResponse.getSsoToken());
    //将用户登录到部落服务
    部落社会服务部落社会服务=
    TribeServiceGenerator.createService(TribeSocialService.class,
    httpClient,新的LenientGsonConverter(新的Gson());
    tribeSocialLaunchService.launch(Utility.getSsoToken(mContext));
    //获取用户id并将其保存到SharedReferences
    部落社会服务部落社会福利服务=
    TribeServiceGenerator.createService(TribeSocialService.class,httpClient,
    User.class,新的WhoAmIDeserializer());
    User tribeUser=tribeSocialWhoAmIService.whoami();
    saveUserId(mContext,tribeUser.getId());
    返回null;
    }
    @凌驾
    受保护的void onPostExecute(void v){
    实用程序启动MainActivity(mContext);
    }
    }
    
    我试图用RxJava实现这一点

    GroupDockService groupDockLoginService=
    GroupDockServiceGenerator
    .createService(GroupDockService.class,
    mHttpClient,GroupDockUser.class,新的GroupDockUserDeserializer());
    groupDockLoginService
    .loginUserRx(“部落”、用户名、密码)
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(新订户(){
    @凌驾
    未完成的公共无效(){
    }
    @凌驾
    公共无效申报人(可丢弃的e){
    Log.e(Log_标签,“我出错了:”+e.getMessage());
    Toast.makeText(mContext,
    getString(R.string.username和密码不正确),
    吐司。长度(短)。show();
    }
    @凌驾
    public void onNext(GroupDockUser-GroupDockUser){
    saveUsernamePassword(mContext、用户名、密码);
    新的LoginUserTask().execute();
    }
    });
    
    在该代码中,我需要执行以下操作

  • 登录成功后,我需要将用户名和密码保存到SavedReferences中
  • 然后,我需要发出网络请求以获取sso令牌
  • 之后,我需要发出第三个也是最后一个网络请求来启动
  • 现在的代码只是调用登录用户,一旦成功,就启动异步任务。理想情况下,我希望将所有请求链接到一个请求中。我一直在尝试使用
    flatmap
    map
    等,但在前面的步骤中,我不知道如何链接这些调用


    有人能给这个照点光吗?谢谢。

    看看这个例子。希望,它会激励你

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

    怎么样?我不知道map或flatmap如何帮助您完成所需的任务