Reputation: 60681
My app has several Activities, including StartActivity
which is declared with
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
in the manifest. I also have an Application
subclass, and it is here that some initialization tasks are kicked off. The initialization code executes in a background thread, so StartActivity
simply displays a splash screen and waits for the background initialization to complete. It is important that control does not pass to any other Activity until the initialization is complete.
Occasionally, after my app has been running, it will be sent to the background by the user pressing the HOME key, and possibly some other apps being opened. If my app is relaunched from the launcher after a short while, the app resumes happily in whatever Activity was active when the app was last open. This is fine.
If there is a delay of a couple of hours before my app is relaunched, then funny things start happening. It appears that the process is restarted - I can tell from log output that my Application.onCreate()
has been called, and the background initialization task is started - but, critically, StartActivity
is bypassed and the system has attempted to go straight to whatever Activity was active last time the app was open.
This seems to me like an impossible situation. It should never be possible for the process to be relaunched (after previously having been terminated, presumably due to inactivity) and jump directly to a non-MAIN
Activity. Either the app is alive, and the last-used Activity can simply be resumed without the app having to reinitialize; or, the app is dead and should reinitialize from scratch, including launching the MAIN
Activity. It should never be in this weird zombie state.
Is my understanding wrong, or is Android doing something totally crazy?
Possibly related: Android: When do classes get unloaded by the system?
Upvotes: 2
Views: 1051
Reputation: 989
Check your settings in Eclipse. Make sure you have the starting activity set to whatever the app defines in the manifest. Sometimes Eclipse likes to set a specific launcher activity as the default and remembers that activity even if your manifest specifies otherwise.
Upvotes: 0
Reputation: 1426
Your Application is in a "stopped" state, hidden, what you called "zombie-state".
When restarting it is calling the onRestart() method of your Activity which was open last time. You need to implement onRestart() method in this Activity.
There you should reinitialize your Application.
For more Information: http://developer.android.com/training/basics/activity-lifecycle/stopping.html
Additional recommendation:
First you should check if initialization is really necessary. In case your initialization-process is an Async-Task you could start it here (maybe with a dialog) or you could send the user straight back to the SplashScreen/MainActivity.
protected void onRestart() {
super.onRestart();
if (!this.getApplicationContext().getIsInitialized()
&& !(this instanceof SplashScreenActivity)) {
Log.v(TAG, "onRestart() starting Initialization of Application");
initialize();
} else {
Log.v(TAG, "onRestart() Application already initialized");
}
}
Upvotes: 1
Reputation: 4725
You need to use onSaveInstanceState to persist any configurations that need to be restored when you're activity is killed and relaunched. You'll get this bundle back in onCreate, and you can update your application to where it left off.
Upvotes: 0