Android/RxJava Как связать сетевые запросы и повторить попытку в случае сбоя
Я пытаюсь связать сетевые запросы с помощью RxJava в Android, а затем повторить попытку при сбое. Я просматривал Stackru о том, как сделать это, не попадая в ад Callback, который приходит с использованием одного только Android и Retrofit. Я могу сделать все это в процедуре, в асинхронной задаче, подобной этой (ниже приведены шаги, которые мне нужно сделать), чтобы войти в систему.
- Войти в систему с именем пользователя / паролем
- Запросить токен SSO, если этот ответ успешен
- Вызовите сервис запуска с этим токеном sso
Я делал это в AsyncTask
это работало только при входе в систему. Однако токен единого входа истекает во время использования приложения, поэтому мне нужно делать запрос каждый раз, когда я вижу, что срок его действия истекает.
Код для 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
- После этого мне нужно сделать третий и последний сетевой запрос на запуск.
Код прямо сейчас делает вызов для входа в систему пользователя, и, как только это успешно, запускает асинхронную задачу. В идеале я хотел бы объединить запросы в один запрос. Я экспериментировал с flatmap
, map
и т. д., и не могу понять, как связать эти вызовы, как я уже говорил выше.
Кто-нибудь может пролить свет на это? Благодарю.
1 ответ
Посмотрите на этот пример. Надеюсь, это вас вдохновит.
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();