I am trying to bind network requests using RxJava in Android and then try again when it is not working. I looked at StackOverflow on how to do this without falling into the hellish hell of Callback that comes with using Vanilla Android and Retrofit alone. I can do all this in a procedure, in such an asynchronous task (below are the steps I need to do) to enter.
- User login with username / password
- Request SSO token if this response is successful
- Call the startup service with this sso token
I did this in AsyncTask, which worked only at login. However, the SSO token expires while using the application, so I need to make a request every time I see that it expires.
The code for AsyncTask is as follows:
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();
GroupDockService groupDockLoginService =
GroupDockServiceGenerator
.createService(GroupDockService.class,
httpClient, GroupDockUser.class, new GroupDockUserDeserializer());
GroupDockUser groupDockUser = groupDockLoginService.loginUser("Tribe", username, password);
Utility.saveAccountSubdomain(mContext, groupDockUser.getGroupDockSubdomain().getSubdomain());
GroupDockService groupDockService = GroupDockServiceGenerator
.createService(GroupDockService.class, httpClient);
GroupDockSsoResponse ssoResponse =
groupDockService.getSsoToken(Utility.getAccountSubdomain(mContext), true);
Utility.saveSsoToken(mContext, ssoResponse.getSsoToken());
TribeSocialService tribeSocialLaunchService =
TribeServiceGenerator.createService(TribeSocialService.class,
httpClient, new LenientGsonConverter(new Gson()));
tribeSocialLaunchService.launch(Utility.getSsoToken(mContext));
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);
}
}
My attempt to make this work with RxJava is similar to
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();
}
});
In this code I need to do the following
- When loginUserRx succeeds, I need to save the username and password in SavedPreferences
- Then I need to make a network request to get the sso token
- After that, I need to run the third and last network request.
The code right now simply calls the login login, and as soon as it succeeds, the asynchronous task starts. Ideally, I would like to combine the queries in a single query. I experimented with flatmap, mapetc., and can't figure out how to connect these calls when I went above.
Can anyone light this light? Thanks.