107

I am creating event search application, we set search criteria from one screen populate in another screen then user can edit search criteria from 3rd screen and goes to 4th screen.

To achieve above task i am using static object which remember the values around the application and i don't need to do any thing extra.

But i am afraid if about static object life cycle in android if low memory found android delete static objects ???

As android supports multi tasking, if user switches to another application and when user comes back application start acting crazy, does static object get removed when it multi task ??? any idea ?? and also suggest holding static object via singleton method is better approach ???

Marian Paździoch
  • 8,813
  • 10
  • 58
  • 103
d-man
  • 57,473
  • 85
  • 212
  • 296

4 Answers4

245

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:

  1. the class is unloaded
  2. the JVM shuts down
  3. 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:

  1. print the uninitialized static in onCreate of your activity -> should print null
  2. initialize the static. print it -> value would be non null
  3. Hit the back button and go to home screen. Note: Home screen is another activity.
  4. Launch your activity again -> the static variable will be non-null
  5. Kill your application process from DDMS(stop button in the devices window).
  6. Restart your activity -> the static will have null value.
starball
  • 20,030
  • 7
  • 43
  • 238
Samuh
  • 36,316
  • 26
  • 109
  • 116
  • 1
    I want to know why I lose my field value in application object if it is not static when I start new activity for example I declare variable current page in application object and its value always return to zero when I open new activity – Mohammed Subhi Sheikh Quroush Feb 14 '13 at 11:12
  • when I call super.onRestoreInstanceState(savedInstanceState); I lose my variable even if they are static , what is the problem ? – Mohammed Subhi Sheikh Quroush Feb 14 '13 at 11:18
  • You need to save them first through `onSaveInstanceState(Bundle outState)` method. – Ionut Negru Nov 22 '13 at 09:34
  • what if I initialize the static instance in `Application.onCreate` ? – suitianshi Jan 08 '15 at 03:44
  • 1
    this is a nice explanation (so no -1) but it's a bit inconsequential: the OP asked explicitly about "low memory situations" (same reason why I'm here), where as far as I know the Os might kill the VM and restart it later with the same parameters, and this case (*IF* it's a real thing) is not covered here... – Rick77 Dec 07 '16 at 14:09
  • after a thorough check, it turns out that Android has different quirks than a standard JVM application and saving anything in the Application as singleton isn't safe. I have added an answer to complement this one. – Rick77 Dec 07 '16 at 14:25
  • I was trying this for a sample application and I found that when I switch to a new Activity, the static variables value is lost. So my case doesn't seem to be agreeing with your answer. I printed the value before calling `startactivity(intent)` and in the `onCreate` of the new activity. They have different values. Any ideas on how I can check what I am doing wrong? – Durga Swaroop Dec 19 '16 at 16:52
  • 1
    @suitianshi I think we can initialize static instances in Application.onCreate, because even if our app goes into background and the process gets killed, as soon as we go back to our app, the Application class will get instantiated and call it's corresponding lifecycle methods again! although I need confirmation on this, I wonder if there could be any scenario where the static instance initialized in Application.onCreate loses its value? – Sarthak Mittal Aug 09 '17 at 06:07
  • Static variables do lose their values in low memory situation. The "example of test" is not relevant - it is not low memory – rommex Sep 14 '17 at 09:17
  • 2
    What I am missing here is an explanation for "1. the class is unloaded"- when would this happen? Would JVM unload a class if it's running low on memory? – stoefln Jun 27 '19 at 19:35
17

Well, the Singleton pattern is also based on using static variables so actually you would be in the same position. While the static approach may work most of the times, it may happen that in some cases when memory is full and another activity takes the foreground before your application moves to its next screen, your activity's process could be killed and you lose the static values. However Android offers a few options of persisting values between states or transmitting them such as:

  • using an Intent, you could pass along your search criteria from activity to activity (similar to a web http request)
  • using application preferences, you could save the values and retrieve them in the activity that needs them
  • using the sqlite database you can persist them in a table and retrieve them later
  • if you need to just save activity state so that on restart, the fields get filled with their previously selected values, you can implement the onSaveInstanceState() activity method - note that this is not recommended for between activities persistance of states.

You can get some code examples of the usage of preferences, intents and the sqlite database by looking at the aegis-shield source code tree in google code or in other open source Android applications.

r1k0
  • 1,406
  • 1
  • 11
  • 26
6

After some research, it turns out that using Application to store singletons is not that great of an idea, unless you are ready to recreate it:

Don't store data in the application object

so while the accepted answer is technically correct, it doesn't provide all information.

As the link above suggests, if you really want to stick with that model, you need to be ready to check for null and recreate the data, if possible.

Community
  • 1
  • 1
Rick77
  • 3,121
  • 25
  • 43
3

@r1k0 is right here. Storing data in static fields of a class will not persist on its own across application process kills and restarts. Android routinely kills processes (running apps) when it needs memory.

Per the Android doc: Activity state and ejection from memory,

The system never kills an activity directly. Instead, it kills the process in which the activity runs, destroying not only the activity but everything else running in the process, as well.

You can save and restore the state of primitives as well Serializable and Parcelable objects using the methods below. These are automatically called during the normal activity lifecycle.

protected void onSaveInstanceState(Bundle state) {}
protected void onRestoreInstanceState(Bundle savedInstanceState){}

So, if you have a class that has only static variables, you can save the state of each field in onSaveInstanceState() and restore them in onRestoreInstanceState(). When Android kills the process that your app is running in, the state of your variables will be saved, and when Android restores your app, the values will be restored in memory in the same state as before.

eric.mcgregor
  • 3,507
  • 2
  • 16
  • 16