I have three activities, let's call them ONE, TWO and THREE. From activity ONE, a button press starts activity TWO. From activity TWO, a button press starts activity THREE.
Simple enough.
Now, activity THREE requires a bit of data accessible from the application (which may or may not be there). In THREE's onResume()
method, a check is made for the data and the activity is finished if it doesn't exist, like so:
@Override
protected void onResume() {
super.onResume();
/* ... get data from app ... */
if (data == null) {
Toast.makeText(this, "Data not found", Toast.LENGTH_SHORT).show();
finish();
return;
}
/* ... other logic ... */
}
When data == null
, THREE finishes, destroys and returns to TWO. All is well.
Now in TWO, pressing the back button calls finish()
on TWO, but TWO never calls onDestroy()
. The user is returned to ONE just fine, but any subsequent intent to go back to TWO does not work and no errors are thrown. TWO is left in a state where it has been finished (and paused), but never destroyed, and as a result cannot resume.
So, why is THREE important in this case? If I remove the finish()
call in the code block above, and rely on a "natural" finishing of THREE (by using the back button), when the user gets back to ONE, TWO has been destroyed correctly.
OK here's where it gets really confusing...
Leaving the finish()
call in place, I can alleviate the hangup by launching THREE directly from ONE, then "naturally" finish it (back button). After THREE is destroyed (a second time), TWO opens as expected.
Everything I've read has said I should be ok calling finish()
within onResume()
for an activity. But in this case, it is leaving something in a bad state and prevents me from destroying the calling activity down the line.
Ideas? or did I turn your brains inside out?
EDIT:
Further exploration uncovered this gem...
Surrounding the finish()
call in THREE with a postDelay()
handler of around 500 millis will allow TWO to close as expected. Like this:
@Override
protected void onResume() {
super.onResume();
/* ... get data from app ... */
if (data == null) {
Toast.makeText(this, "Data not found", Toast.LENGTH_SHORT).show();
Handler h = new Handler();
h.postDelayed(new Runnable() {
@Override
public void run() {
finish();
}
}, 500);
return;
}
/* ... other logic ... */
}
Not exactly my idea of a fix...
an activity is not finished / destroyed on back pressed.
Use
@Override
public void onBackPressed()
{
finish();
}