Using Android 2.1+. I have a service that gets killed from time to time by the OS (due to memory pressure I guess).
This service maintains some states using static member fields of classes. I'm expecting the static fields to keep their values despite the service being killed and restarted by the OS.
But it seems that it doesn't happen like this. After a restart, static variables are reset to default value.
Is it what is supposed to happen? Should I use another way to keep a persistent state despite kill/restart?
Yes, this is what happens when your service is killed. The program is taken out of memory, and when it's reloaded into memory, the default values for the static variables are all assumed. Put another way, the byte code for your program can't change from execution to execution.
It's generally considered bad from to use static variables to keep state. Try storing them in presistent storage, like a sqlite database.
Related
I have an intentService in my application that is scheduled to be called every 5 minutes. In that service I am using values shared with the rest of the app (Strings, int..). I am using Singleton to hold these values. This works fine most of the times.
However sometimes, for no reason (at least that I can see), the values are lost, and the app crashes due to that. It seems that the Singleton looses it state.
I have read that Android can delete information from memory that it finds unnecessary. For this reason in my activities, I have saved the values in a bundle when the app goes idle (onPause and onResume).
Now the problem is that in the intentService the case is different. I am calling the service every 5 minutes using a timer.
I need a way to retain the values in the singleton. I would rather not save them in the database (it seems a heavy task to do this every 5 minutes), there should be a simpler way.
I hope that was clear, I am grateful for any insight.
If your process is terminated by the system, all the data in memory will be lost. You cannot rely on your process being alive all the time so that you can keep that data in your singleton. Either store that data in a SQLite database, store it in shared preferences, or save it to a file that you can read from the next time your singleton is initialized.
What I doubt, as you use Singleton class in your application, might be android kill your application instance on memory low scenario. So you can lost your singleton class object also. Instead of this, I suggest you have to use SharedPreferences
Sorry for my English
I have some class that has static (== global) methods such as setListener(), removeListener(). It stores quite few listeners (which are global) and these listeners take very low memory.
But what will happen if the system kills my app's activity because of the lack memory for other application?
Could happen that the system will remove these global listeners?
If the system kills your app, it kills the VM - static variables are lost.
Depending on what you're doing, you probably don't want to register short lived listeners in a static way.
Why I shouldn't use static objects in an Activity or don't make static calls to an Activity?
A more reasonable statement would be saying be extremely careful about using static variables in Android.
You can use them, but be aware that you application can and will be killed by the OS, and restarted when the user returns to the app (i.e. maybe from the recent apps list). This results in your application having many different entry points, and you can't assume the static variable will be initialized.
For example, setting a static variable in your application's first Activity, and assuming it will always be set is a big mistake.
Also, be cautious about storing anything that has a reference to an Activity as a static variable, because this tends to be a common source of consuming memory unnecessarily. For example, storing a View in a static variable is almost certainly a mistake, because it will prevent an entire Activity from being garbage collected if not cleared out.
It is a general good practice to avoid making things static that don't need to be since they increase the chances of memory leaks. If you're always holding a reference to some data the GC won't be able to free it.
Is there any way to avoid static data loss in Android if device is kept idle ?
I am having static object which will store some values from activity UI.
If device is kept idle for 4-5 hours that static object will be removed to use memory for other running applications.
If I am doing it wrong, is there any other way to avoid this ?
You can't avoid it. Android can kill your process at any time and does not guarantee to call you back.
This only happens if your app goes to the background. Save your data in onPause() and reload it in onResume(). See the Android documentation for Activity lifecycle for more information.
No, that's how Android is meant to work.
Simply, if data are meant to be persistent, ie if its lifecycle spans beyond the one of the Activity which created it, save it on a persistent storage (ie internal memory), in a flat file or in a database depending if the data has an inner structure or not.
I noticed that when my application encounters an error, the value of my application context variables are also reinitialized to its original value (not the updated value). Based from my understanding, this happened because the application was recreated.
How can I save and restore the values of my application context variables when an application error occurs? I'll also be glad if you could give a more detailed explanation on how things are working on the background of my application when it encounters an error.
Note: I read that one of the solution for this is by using SharedPreferences. However, SharedPreferences saves the data even when the application is dead. I don't want to save the data when the application is dead. I only want to save the data when the application is alive or on background.
How can I save and restore the values of my application context variables when an application error occurs?
First, don't have an unhandled exception.
Second, don't rely on static data members or custom Application subclass instances. There are many scenarios in which your process will be terminated and those values go away. They should be used for an in-memory cache of persistent content, and little else.
Sometimes, unhandled exceptions are truly unexpected, but these should be infrequent and usually tied to specific devices (e.g., ran out of storage space). Everything else represents a bug in your app, and you must fix the bugs.