My app contains 2 activities both of them depend on some static objects.I'm curious will android terminate whole app and clean my static fields if both activities are destroyed(for instance when device runs out of mem)?
Lets start with a bit of background: What happens when you start an application?
The OS starts a process and assigns it a unique process id and allocates a process table.A process start an instance of DVM(Dalvik VM); Each application runs inside a DVM.
A DVM manages class loading unloading, instance lifecycle, GC etc.
Lifetime of a static variable: A static variable comes into existence when a class is loaded by the JVM and dies when the class is unloaded.
So if you create an android application and initialize a static variable, it will remain in the JVM until one of the following happens:
the class is unloaded
the JVM shuts down
the process dies
Note that the value of the static variable will persist when you switch to a different activity of another application and none of the above three happens. Should any of the above three happen the static will lose its value.
You can test this with a few lines of code:
print the uninitialized static in onCreate of your activity -> should print null
initialize the static. print it -> value would be non null
Hit the back button and go to home screen. Note: Home screen is another activity.
Launch your activity again -> the static variable will be non-null
Kill your application process from DDMS(stop button in the devices window).
Restart your activity -> the static will have null value.
The answer to your question.
yes, if all of your activities are destroyed your application process will be killed.
Credits Samuh
Related
I have an Activity, where I initialize a class member variable in onCreate(). In some case, I need to startActivity() which means this Activity turn into stopped state. When I come back, I need to use the variable.
This works OK in most phones, but I also get some crash from my users because the member become null on their phones. This member just contains some String and a POJO.
Does Android clean up Activity's member variable to free up memory?
Those member variables will be cleared out if onDestroy is called, even if the activity isn't finished. You can simulate this by turning on "Don't keep activities alive" in developer settings. Once that's enabled, start your activity and then pause it (i.e. hit the home button)
To get around this, you'll need to store those member variables in onSaveInstanceState, and then restore them using the savedState bundle in onCreate
Let's assume that I have an Android App with two Activities (Activity1 and Activity2). In Activity1 I declare a public static Boolean foo = true.
When I finish() Activity1 and move to Activity2, I am able to see that "foo" variable has value true
But when the System has low memory (e.g. because there are many apps running on the device) then, when I am on Activity2 I see that the value of "foo" variable is null.
How is this explained?
It's important to note that the life of a static variable is tied to the process not the activity. Even if your activity is destroyed, the static variable will still be alive (which is why you see it's value set to true). It's only when the process is destroyed that the static variable will be freed properly.
This is also one of the reasons you shouldn't use static variables to hold references to activities, contexts, or views. Huge memory leaks waiting to happen.
For your particular scenario, this means that:
Act1 created & set the variable; You've moved from Act1 to Act2
The processes is killed in the BG
When the system attempts to restore you, you end up back at Act2
However, since the initialization of that variable happened in Act1, (which hasn't been initialized) the variable doesn't get set.
If the process is killed then all static variables will be reinitialized to their default values.
So whatever value you have set in Activity1 will not persist
What is the Life cycle of static variables in Android?
I found that sometimes some static variables bound to activities happened to be uninitialized even though they've previously been initialized! I thought that when a static variable is initialized it stays so for the entire life of the application, but this doesn't seem to be the case.
Android may kill you app if it runs out of memory and all it's activities are in background (not visible). But you activity remains in history and user may activate it again. In this case system will recreate your app and restore it's state.
To deal with this case you should store state of your app and activities in persistant memory (files, database, etc).
More info you may find here http://developer.android.com/reference/android/app/Activity.html#SavingPersistentState
It depends were you define it, for example :
If the process is killed then all static variables will be reinitialized to their default values.
So whatever value you have set in Activity A will not persist. The same goes when an activity is destroyed.
I have an ArrayList of ChatBox's which is a class that extends activity.
My question is, is that if the systems kills an instance of my ChatBox activity, what will happen if i use my reference to the ChatBox class to try and update the ui with text im sending through a handler?
You will get DeadObjectException...
.. and besides the exception, you will leak the whole activity. Any object that stores a Context (Views and Bitmaps for example) that are kept beyond the activity lifecycle will cause it to not be GC'ed.
I suppose the nature of your app is very asynchronous and you can't tell when the activity has been stopped. In this case take a look a WeakReference as a means to store a reference to your activity. This way, if android decides to stop it, it will successfully deallocate it, and you will be able to tell if the activity is alive or not in your chatboxes before messing up:
WeakReference<Activity> myWeakActivity=new WeakReference(realActivity);
.
.
Activity myActivity=myWeakActivity.get();
if (myActivity==null) {
// Activity not active for whatever reason.
}
You can try to change several times between portrait & landscape (this restarts the activity). Take a close look to your Heap Size. If you are leaking views you'll see it keeps growing & growing until it will eventually die .
I am using a separate class with only static fields, to store current application data.
It is partly populated from sharedpreferences on application startup. The rest is data like results of some action, used for further browsing these results (multiple activities that use the results).
I can go to the home screen, start other applications etc. and when I return to my own application it just works correctly.
However, since the new Error Reporting feature I get some bug reports all related to a nullreference error. The object that is null is a reference to the static field in the mentioned separate class.
Since I cannot reproduce the bug I am inclined to think this is due to the application getting killed due to low memory, and when it relaunches it calls the oncreate from the activity that the user was currently in. However all the static data in the separate class is not restored and thus it crashes.
I would like to know: Is there a way to force the application to "restart" completely, and not start with the last used activity if it gets killed? Or is that standard behaviour?
Can I do this programmatically? Like when the static fields are null, restart app?
Restarting the activity where the user was is normal behaviour - the idea is to make it look to the user like the app was never closed. There are two things you can look at:
protected void onSaveInstanceState(Bundle outState){
// This gets called by the system when it's about to kill your app
// Put all your data in the outState bundle
}
That bundle is the same one that gets passed to the activity in onCreate(). You can then get any necessary information out of it and restore the values in the static class.
The other way is to simply check the values in the onResume() method of any of your activities. If the values are null or wrong in some way, then you can call start the original activity and finish() the one being started.