The android app I am working on overrides the Application class to store lightweight state (username, gps location, etc) in static vars. Most of this state is set in OnCreate of the launch activity (username retrieved from prefs, location listener runs). Is it safe to rely on the launch activity to initialize the Application class? Are there any cases where the Application class might be re-created without the Launch activity also being created?
The question comes up because I ran into a null pointer exception accessing a variable in the Application class on resuming the app after the phone was asleep for several hours (the app was left in the foreground before phone went to sleep). Is it possible that the process was killed while the phone was asleep and on waking the phone, the Application class was re-created, the top activity in the stack was resumed, but the launch activity.onCreate wasn't run thus the Application class wasn't initialized?
Note that I have tried to test these kinds of scenarios by Forcing the App to stop using Settings / Manage applications. However, I'm not able to recreate the problem. On the next run, the Application class is created, followed by the launch activity.onCreate.
Is it safe to assume that the Application class instance will exist as long as the process, and that when the Application class is created it is equivalent to "restarting" the application ie. start with a new activity stack (and first activity on stack is the launch activity)?
An Android activity goes through six major lifecycle stages or callbacks. These are: onCreate() , onStart() , onResume() , onPause() , onStop() , and onDestroy() . The system invokes each of these callbacks as an activity enters a new state.
Overview. The Application class in Android is the base class within an Android app that contains all other components such as activities and services. The Application class, or any subclass of the Application class, is instantiated before any other class when the process for your application/package is created.
No. Your entire application can be killed and recreated with the task stack intact; this lets the system reclaim memory on devices that need it while still presenting a seamless illusion of multitasking to the end user. From the docs:
A background activity (an activity that is not visible to the user and has been paused) is no longer critical, so the system may safely kill its process to reclaim memory for other foreground or visible processes. If its process needs to be killed, when the user navigates back to the activity (making it visible on the screen again), its onCreate(Bundle) method will be called with the savedInstanceState it had previously supplied in onSaveInstanceState(Bundle) so that it can restart itself in the same state as the user last left it.
That is, the process (which the Application is tied to) can be killed off but then restarted, and the individual activities should have enough info to recreate themselves from what they've saved before being killed, without relying on global state set in the process by other Activities.
Consider storing persistent shared state that needs initialization by an Activity in either a SharedPreference or SQLite database, or passing it to Activities that need it as an Intent extra.
You can test the scenario by killing the process
of your running application.
Step 1. Open your app, and then press Home
button to hide it into background.
Step 2. Invoke adb shell
Step 3. Enter command su
(you have to get ROOT permission in order to kill process)
Step 4. ps
(list all running process ID and find yours)
Step 5. kill 1234
(assume your application running on process 1234)
Step 6. Then, go back to your device and click the launch icon again. You may find the last activity on activity stack is reopen. You may also find onRestoreInstanceState()
method is called for the activity.
In short: do initilization in YourApplication.onCreate
, not some LaunchActivity
Docs to check:
- Processes and Threads
- API Guides > Activities
Is it safe to rely on the launch activity to initialize the Application class?
Yes, as long as you remember that Application can exist longer that Activity and the Activity may be killed and recreated. I am not sure what Intent will resurrected Activity get: LAUNCH or VIEW (For scenario when activity was killed as too heavy, while there was long running service binded to app )
Are there any cases where the Application class might be re-created without the Launch activity also being created?
yes, if the last visible activity was not LaunchActivity
check Android application lifecycle and using of static
Is it possible that the process was killed while the phone was asleep and on waking the phone, the Application class was re-created, the top activity in the stack was resumed, but the launch activity.onCreate wasn't run thus the Application class wasn't initialized?
If there were several different Activities launched A, B, C and them whole process killed, then I think Android OS is good with only creating Application and C activity, while A and B would be re-creted on access, that is on returning to them.
Is it safe to assume that the Application class instance will exist as long as the process,
yes
and that when the Application class is created it is equivalent to "restarting" the application ie. start with a new activity stack (and first activity on stack is the launch activity)?
I not sure when restarting the launch activity would be called first,
but the last, i.e. the one that user should see.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With