我正在尝试在 Android 中使用 RxJava 链接网络请求,然后在失败时重试。我一直在查看 StackOverflow,了解如何在不陷入单独使用 vanilla Android 和 Retrofit 所带来的回调 hell 的情况下执行此操作。我可以在一个过程中完成这一切,在这样的异步任务中(下面是我需要执行的步骤)登录。
- 使用用户名/密码登录用户
- 如果响应成功,则请求 SSO token
- 使用该 sso token 调用启动服务
我一直在 AsyncTask
中执行此操作,该操作仅在登录时有效。但是,SSO token 在应用程序使用期间过期,因此我需要在每次看到时发出请求它会过期。
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();
}
});
在该代码中,我需要执行以下操作
- 当loginUserRx成功后,我需要将用户名和密码保存到SavedPreferences
- 然后我需要发出网络请求以获取 sso token
- 之后,我需要发出第三个也是最后一个网络请求才能启动。
现在的代码只是调用登录用户,一旦成功,就会启动异步任务。理想情况下,我想在那个请求中将所有请求链接在一起。我一直在试验 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();
关于java - Android/RxJava 如何链接网络请求并在失败时重试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35400816/