I have a simple fragment that handles logins for my application. Since I'm dealing with login requests, I do not want to cache them. This strategy works fine until I introduce a suspend or orientation change in the middle of the request. When a user clicks the login button I display a ProgressDialog. This goes away when I get the response (success or fail). If I go to the home screen and then go back into the app during the middle of a login request, my Listener never gets notified and as a result my ProgressDialog doesn't get dismissed and my application is frozen. I tried adding spiceManager.getFromCache in my onStart. This helps, but the result is always null when the app tries to recover... this makes sense since the results aren't cached. What is the proper way to configure my listener to be notified in this scenario?
// using Jackson2SpringAndroidSpiceService
public void onStart() {
super.onStart();
spiceManager.start(getActivity());
spiceManager.addListenerIfPending(AccessTokenResponse.class, null,
new AccessTokenResponseRequestListener());
//spiceManager.getFromCache(AccessTokenResponse.class,
// null, DurationInMillis.ALWAYS_EXPIRED,
// new AccessTokenResponseRequestListener());
}
private void performRequest(String username, String password) {
progressDialog = ProgressDialog.show(getActivity(), "", "Logging in...", true);
LoginFragment.this.getActivity().setProgressBarIndeterminateVisibility(true);
LoginRequest request = new LoginRequest(username, password);
spiceManager.execute(request, null, DurationInMillis.ALWAYS_EXPIRED, new AccessTokenResponseRequestListener());
}
private class AccessTokenResponseRequestListener implements RequestListener<AccessTokenResponse> {
@Override
public void onRequestFailure(SpiceException e) {
//update your UI
if(progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
buttonLogin.setEnabled(true);
Log.e(TAG, "Login unsuccessful");
if(e.getCause() instanceof HttpClientErrorException)
{
HttpClientErrorException exception = (HttpClientErrorException)e.getCause();
if(exception.getStatusCode().equals(HttpStatus.BAD_REQUEST))
{
Log.e(TAG, "Login unsuccessful");
Toast.makeText(getActivity().getApplicationContext(),
"Wrong username/password combo!",
Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getActivity().getApplicationContext(),
"Login unsuccessful! If the problem persists, please contact support.",
Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(getActivity().getApplicationContext(),
"Login unsuccessful! If the problem persists, please contact support.",
Toast.LENGTH_LONG).show();
}
}
@Override
public void onRequestSuccess(AccessTokenResponse accessToken) {
//update UI
if(progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
buttonLogin.setEnabled(true);
if (accessToken != null) {
OnAuthenticatedListener listener = (OnAuthenticatedListener) getActivity();
listener.userLoggedIn(editTextUsername.getText().toString(), accessToken);
}
}
}
Use cache. Execute request with some cache key
spiceManager.execute(request, "your_cache_key", DurationInMillis.ALWAYS_EXPIRED, new AccessTokenResponseRequestListener());
and in listener remove response on this request from cache if it returned successfully before you switched to another activity as you do not want to cache the account information as per your requirement.
@Override
public void onRequestFailure(SpiceException e) {
....
spiceManager.removeDataFromCache(AccessTokenResponse.class);
....
}
@Override
public void onRequestSuccess(AccessTokenResponse accessToken) {
if (accessToken == null) {
return;
}
....
spiceManager.removeDataFromCache(AccessTokenResponse.class);
....
}
In onStart try to get cached response if you switched to another activity and now come back to the previous activity. This return response which arrive after you call spiceManager.shouldStop(). Otherwise return null.
spiceManager.getFromCache(AccessTokenResponse.class, "your_cache_key", DurationInMillis.ALWAYS_RETURNED, new AccessTokenResponseRequestListener());