As I understand it, an activity being destroyed is not equivalently to an activity being finished.
- Finished
- The activity is removed from the back stack.
- It can be triggered by the program (e.g. by calling
finish()
), or by the user pressing the back key (which implicitly callsfinish()
). - Finishing an activity will destroy it.
- Destroyed
- The Android OS may destroy an invisible activity to recover memory. The activity will be recreated when the user navigates back to it.
- The activity is destroyed and recreated when the user rotates the screen.
- Reference: Recreating an Activity
So how do I finish a destroyed activity? The finish()
method requires an Activity
object, but if the activity is destroyed, I have no Activity
object - I am not supposed to be holding a reference to a destroyed activity, am I?
Case study:
I have an activity a
, which starts b
, which in turn starts c
(using Activity.startActivity()
), so now the back stack is:
a → b → c
In c
, the user fills out a form and tap the Submit button. A network request is made to a remote server using AsyncTask
. After the task is completed, I show a toast and finish the activity by calling c.finish()
. Perfect.
Now consider this scenario:
While the async task is in progress, the user switches to another app. Then, the Android OS decided to destroy all 3 activities (a
, b
, c
) due to memory constraints. Later, the async task is completed. Now how do I finish c
?
What I have tried:
- Call
c.finish()
:- Can't, because
c
is destroyed.
- Can't, because
- Call
b.finishActivity()
:- Can't, because
b
is destroyed.
- Can't, because
Use
Context.startActivity()
withFLAG_ACTIVITY_CLEAR_TOP
so as to raiseb
to the top, thus finishingc
:// appContext is an application context, not an activity context (which I don't have) Intent intent = new Intent(appContext, B.class); // B is b's class. intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); appContext.startActivity(intent);
- Failed,
appContext.startActivity()
throws an exception:
- Failed,
android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?
Edit: Clarification: I need to wait until the async task finishes and decide whether to finish c
based on server's response.
*what*.finish()
? I have no activity. – Jocelin