I going to contribute my approach to handling this rotation issue. This may not be relevant to OP as he's not using AsyncTask
, but maybe others will find it useful. It's pretty simple but it seems to do the job for me:
I have a login activity with a nested AsyncTask
class called BackgroundLoginTask
.
In my BackgroundLoginTask
I don't do anything out of the ordinary except to add a null check upon calling ProgressDialog
's dismiss:
@Override
protected void onPostExecute(Boolean result)
{
if (pleaseWaitDialog != null)
pleaseWaitDialog.dismiss();
[...]
}
This is to handle the case where the background task finishes while the Activity
is not visible and, therefore, the progress dialog has already been dismissed by the onPause()
method.
Next, in my parent Activity
class, I create global static handles to my AsyncTask
class and my ProgressDialog
(the AsyncTask
, being nested, can access these variables):
private static BackgroundLoginTask backgroundLoginTask;
private static ProgressDialog pleaseWaitDialog;
This serves two purposes: First, it allows my Activity
to always access the AsyncTask
object even from a new, post-rotated activity. Second, it allows my BackgroundLoginTask
to access and dismiss the ProgressDialog
even after a rotate.
Next, I add this to onPause()
, causing the progress dialog to disappear when our Activity
is leaving the foreground (preventing that ugly "force close" crash):
if (pleaseWaitDialog != null)
pleaseWaitDialog.dismiss();
Finally, I have the following in my onResume()
method:
if ((backgroundLoginTask != null) && (backgroundLoginTask.getStatus() == Status.RUNNING))
{
if (pleaseWaitDialog != null)
pleaseWaitDialog.show();
}
This allows the Dialog
to reappear after the Activity
is recreated.
Here is the entire class:
public class NSFkioskLoginActivity extends NSFkioskBaseActivity {
private static BackgroundLoginTask backgroundLoginTask;
private static ProgressDialog pleaseWaitDialog;
private Controller cont;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (CredentialsAvailableAndValidated())
{
gotoMainMenu();
return;
}
setContentView(R.layout.login);
populateStoredCredentials();
}
@Override
public void onPause()
{
super.onPause();
saveCredentialsToPreferences(false);
if (pleaseWaitDialog != null)
pleaseWaitDialog.dismiss();
}
@Override
public void onResume()
{
super.onResume();
if ((backgroundLoginTask != null) && (backgroundLoginTask.getStatus() == Status.RUNNING))
{
if (pleaseWaitDialog != null)
pleaseWaitDialog.show();
}
}
private void gotoMainMenu()
{
startActivity(new Intent(getApplicationContext(), NSFkioskMainMenuActivity.class));
finish();
}
private void saveCredentialsToPreferences(boolean setValidatedBooleanTrue)
{
SharedPreferences settings = getSharedPreferences(APP_PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor prefEditor = settings.edit();
EditText usernameText = (EditText) findViewById(R.id.editTextUsername);
EditText pswText = (EditText) findViewById(R.id.editTextPassword);
prefEditor.putString(USERNAME, usernameText.getText().toString());
prefEditor.putString(PASSWORD, pswText.getText().toString());
if (setValidatedBooleanTrue)
prefEditor.putBoolean(CREDS_HAVE_BEEN_VALIDATED, true);
prefEditor.commit();
}
private boolean CredentialsAvailableAndValidated() {
SharedPreferences settings = getSharedPreferences(APP_PREFERENCES,
MODE_PRIVATE);
if (settings.contains(USERNAME) && settings.contains(PASSWORD) && settings.getBoolean(CREDS_HAVE_BEEN_VALIDATED, false) == true)
return true;
else
return false;
}
private void populateStoredCredentials()
{
SharedPreferences settings = getSharedPreferences(APP_PREFERENCES,
MODE_PRIVATE);
settings.getString(USERNAME, "");
EditText usernameText = (EditText) findViewById(R.id.editTextUsername);
usernameText.setText(settings.getString(USERNAME, ""));
EditText pswText = (EditText) findViewById(R.id.editTextPassword);
pswText.setText(settings.getString(PASSWORD, ""));
}
public void loginButtonClick(View view)
{
if (phoneIsOnline())
{
EditText usernameText = (EditText) findViewById(R.id.editTextUsername);
EditText pswText = (EditText) findViewById(R.id.editTextPassword);
backgroundLoginTask = new BackgroundLoginTask();
backgroundLoginTask.execute(usernameText.getText().toString(), pswText.getText().toString());
}
else
{
String notOnlineMessage = getResources().getString(R.string.noNetworkAccessAvailable);
Toast toast = Toast.makeText(getApplicationContext(), notOnlineMessage, Toast.LENGTH_SHORT);
toast.show();
}
}
public class BackgroundLoginTask extends AsyncTask<Object, String, Boolean>
{
private Exception e = null;
@Override
protected void onPreExecute()
{
cont = Controller.getInstance();
String pleaseWait = getResources().getString(R.string.pleaseWait);
String commWithServer = getResources().getString(R.string.communicatingWithServer);
if (pleaseWaitDialog == null)
pleaseWaitDialog= ProgressDialog.show(NSFkioskLoginActivity.this, pleaseWait, commWithServer, true);
}
@Override
protected Boolean doInBackground(Object... params)
{
try {
return cont.validateCredentials((String)params[0], (String)params[1]);
} catch (Exception e) {
this.e=e;
return false;
}
}
@Override
protected void onPostExecute(Boolean result)
{
if (pleaseWaitDialog != null)
{
pleaseWaitDialog.dismiss();
pleaseWaitDialog = null;
}
if (e != null)
{
String networkError = getResources().getString(R.string.serverErrorException);
Toast toast = Toast.makeText(getApplicationContext(), networkError, Toast.LENGTH_SHORT);
toast.show();
}
else
{
if (result == true)
{
saveCredentialsToPreferences(true);
gotoMainMenu();
}
else
{
String toastText = getResources().getString(R.string.invalidCredentialsEntered);
Toast toast = Toast.makeText(getApplicationContext(), toastText, Toast.LENGTH_SHORT);
toast.show();
}
}
}
}
}
I am by no means a seasoned Android developer, so feel free to comment.