46

when I declare and initialize a variable as static in my main activity and the activity gets destroyed. Can I still access the content of the variable?

For example to always access a AsyncTask which I store to this variable? What I want is to be able to access to it also after an orientation change.

maysi
  • 5,457
  • 12
  • 34
  • 62
  • 1
    I have had huge problems because of static variables. The memory clean-up is unpredictable and can lead to unexpected failure. You can force a memory clean-up by clearing the RAM (hold home button to get there). If your app still works, you should be safe ;-) – Vincent van der Weele Jul 27 '13 at 18:18
  • @EmmanuelMess: I am unclear what you are looking for that is not provided by the current answers, such as [mine](https://stackoverflow.com/a/17900523/115145). – CommonsWare Aug 18 '19 at 23:07
  • 2
    @CommonsWare You say that the varible lives as long as the process is alive, but you don't provide a reference. The bounty is mostly to find an answer that is supported by something other than "that SO answer sayed...". – EmmanuelMess Aug 19 '19 at 14:24

15 Answers15

25

Static variables are associated with a class and they will live as long as the class is in the memory,and destroy when class gets unloaded (which very rarely happens).

In Android you have seen that when we close any application it does not close completely, It remains in the recent application stack, That you can see by holding in the home button(On Most Devices).

Android itself kicked out those recent app when the other app needs memory

Community
  • 1
  • 1
T_V
  • 17,440
  • 6
  • 36
  • 48
  • 3
    proof, link? why that class and his class loader couldn't be unload from memory, while app continues running? – k4dima Dec 19 '13 at 20:17
9

If the process is killed then all static variables will be reinitialized to their default values.

This is mainly because, when you restart the application, a new instance is created and the static variable will be reinitialized.

JNL
  • 4,683
  • 18
  • 29
  • Which means that, if activity's launch mode is singleInstance, for instance, it's going to be there until device gets rebooted, right? – Budimir Grom Jan 28 '15 at 13:38
  • no. hit home button. open ddms and kill the process. return to app. this is a simple way to reproduce what the OS will randomly do to your application when it feels like it, and you will see that your static variables are gone – dabluck Mar 11 '15 at 20:08
  • this is *NOT* what I've seen claimed elsewhere. sometimes android can evict your app from memory while retaining an empty process (to make restart faster). if the app is restarted the old static fields might still be around because the classes were never unloaded. At least that's the claim I've seen (reddit). if this is true than sometimes statics might be cleared, sometimes not. – Merk Dec 06 '18 at 21:25
8

Static variables are tied to the class itself. As long as the class is in memory, the variable will be kept.

Classes rarely get garbage collected as they live in what is called the Permanent Generation of memory space (you can find more about how generational GC works here https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html).

You can look at https://developer.android.com/topic/performance/memory-overview to get a better understanding of how memory is managed in Android, but unless your app is doing something very very unusual, the permanent generation is allocated all the memory it needs to hold all it's classes and will not be garbage collected.

Orientation changes will not clear a static variable, however if that's your goal using a static variable isn't very appropriate. You can keep instance state when orientation changes by using setRetainInstance or similar (see Android: how do I prevent class variables being cleared on orientation change for an answer)

Alon Bar David
  • 1,757
  • 14
  • 15
  • 1
    Now the Arch components Live data We dont need to retain data through setRetainInstance https://developer.android.com/topic/libraries/architecture/livedata – Gem Aug 26 '19 at 07:16
4

Can I still access the content of the variable?

Assuming that by "destroyed" you mean something like the user pressing BACK, yes.

Static data members live for the life of the process.

For example to always access a AsyncTask which I store to this variable? What I want is to be able to access to it also after an orientation change.

That is not an appropriate solution. Use a retained fragment, or use onRetainNonConfigurationInstance().

Community
  • 1
  • 1
CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • ```onRetainNonConfigurationInstance()``` is final in the support framework so this doesn't work. – maysi Jul 27 '13 at 17:24
  • 1
    @Simon: Then use a retained fragment (i.e., a fragment, on which you have called `setRetainInstance(true)`, that manages the `AsyncTask`). See https://github.com/commonsguy/cw-omnibus/tree/master/Threads/AsyncTask – CommonsWare Jul 27 '13 at 17:25
  • hm I still don't really understand how to go on. I have a main avtivity which is a ```SherlockFragmentActivity```and it has a refresh method. In this method a new object of my ```AsyncTask``` is created and executed. When the Task starts (```onPreExecute()```) a ```Dialog``` is created and the message of the dialog is 3 times changed in my ```doInBackground()``` and in the ```onPostExecute()``` the dialog gets dismissed. But when the orientation gets changed there are some problems. e.g. there is no dialog more. so how should I go on? should I make a new qustion where I explain this detailed? – maysi Jul 27 '13 at 18:12
  • 1
    @Simon: You should be using a `DialogFragment` for managing your `Dialog`. AFAIK, that `DialogFragment` could be retained for managing your `AsyncTask`, though I have never tried this, as I avoid dialogs like the plague. – CommonsWare Jul 27 '13 at 18:23
  • Okay I try to use this. Thanks so far :) Whats the reason for avoiding dialogs? – maysi Jul 27 '13 at 18:28
  • @Simon: I try to avoid modal UIs. Even if I'm loading something in the background, let the user use whatever of the app that they can while that loading is going on. – CommonsWare Jul 27 '13 at 18:35
  • okay sounds comprehensible. I also thought about this but how do you inform the user about the preogress? and isn't there a problem when the user change the activity and you need to access the context e.g for a Toast? – maysi Jul 27 '13 at 18:42
  • @Simon: "but how do you inform the user about the preogress?" -- show a `ProgressBar` somewhere. For example, you might have one normally set to `View.GONE` that you make `View.VISIBLE` while the download is going on. "and isn't there a problem when the user change the activity and you need to access the context e.g for a Toast?" -- well, I don't use `Toast` much in production code either. Beyond that, it really depends on what you're writing and how you're writing it (e.g., would an `IntentService` be better than an `AsyncTask`), and that's way beyond the scope of a StackOverflow comment. – CommonsWare Jul 27 '13 at 18:46
  • okay I started a new question. have a look: http://stackoverflow.com/questions/17901339/what-is-a-good-way-to-inform-the-user-about-the-progress – maysi Jul 27 '13 at 18:58
4

Static variables are created once the enclosing class is loaded into the memory. You may initialize the static variables at the load time in a static block or while the code is already running like in your case. Static variables are related to the type rather than single instance of the type because of that once a static variable is created, it lives as long as the process which contains it(in android, it means that it lives along with the application). The problems it may cause are:

  • Context leaks (Like Activity): The static variable keeps reference to a context or to a object(like a view) which keeps reference to it.
  • Huge burden on memory: If you use static variables in types whose life scope is shorter than the application, the process keeps all static variables alive. For example in ten activities you keep a bitmap as a static variable. In this case all bitmaps are alive and occupy place in memory. At the end, memory and the system cannot tolerate the burden and throw MemoryOutBoundException.
  • Crashes: For example in a scenario, you create an object in an activity then you store it in the activity as a static variable. Then, you go to the next activity. In the second activity, you are sure about that the previous activity's static variable is not null and most of time it is true. However if the system kills the process and recreates it, the static variable doesn't persist its object. What I want to say is that in an event driven environment, to manage static variables is not an easy task.

For your case: ViewModel architecture component persists objects across the configuration changes. You can use it however you still need to be careful about context leaks. Another option is to use a fragment without a UI. You call function setRetainInstance(true) in the fragment and the system persists this fragment across configuration changes. This fragment keeps your data and you can get this fragment via fragment manager after a configuration change occurs. Actually the latter option is underlying mechanism of the ViewModel. For multithreaded cases like AsyncTask, the operation running in a separate thread should not keep reference to the context. You should run the task in a separate layer then update the necessary fields in the viewModel or retained fragment.

M.ekici
  • 765
  • 4
  • 10
1

They stay even if you close the app with pressing back button as long as you don't clear them from the recent apps.Proof : well I've tested it you can too it's easy ;).

Steve Moretz
  • 2,758
  • 1
  • 17
  • 31
0

Android has concept of empty process which says your app may not be removed from memory if it is frequently used by the user even if all its components are destroyed(activities, services, and/or broadcast receivers) , in which case static variables will not be cleared of completely.

Application class is the best way to share some temporary variables between components because application class will be created properly on application startup time and will be cleared of once user exits app.

Reference: http://skillgun.com/question/9849/android-provab/face-to-face-round/if-i-close-the-application-will-it-destroy-all-the-static-variables

Community
  • 1
  • 1
Android Developer
  • 9,157
  • 18
  • 82
  • 139
0

I believe I finally found you a reference -

The garbage collector automatically cleans up unused objects. An object is unused if the program holds no more references to it. You can explicitly drop a reference by setting the variable holding the reference to null.

https://docs.oracle.com/javase/tutorial/java/javaOO/summaryclasses.html

To be clear, it is possible for static variables to remain initialized preventing the class to be properly garbage collected (aka a memory leak).

Brandon McAnsh
  • 992
  • 8
  • 18
  • The object here is the class object that holds the reference to the static variable? When is this garbage collection done on Android apps for these types of objects? Is this reference applicable to Android (does the garbage collection of static variables work in the same way on Android as in plain old Java)? – EmmanuelMess Aug 21 '19 at 18:03
  • Yes it works the same way in Android, it will be cleaned up/GC as long as there is no attachments to any variables/instances. – Brandon McAnsh Aug 21 '19 at 19:28
  • You only answered the last question and you seem to miss the point of adding references of how this works "in android" as the bounty details say. – EmmanuelMess Aug 21 '19 at 19:32
  • I don't believe the default classloader will ever unloaded a class. – rds Aug 21 '19 at 20:06
  • The ClassLoader most certainly does unload classes as needed; otherwise memory use would always be increasing (and never decreasing) when profiling the app. The static variables are dereferenced/unloaded along with the class as long as they are properly uninitialized. – Brandon McAnsh Aug 22 '19 at 00:48
  • "The ClassLoader most certainly does unload classes as needed; otherwise memory use would always be increasing (and never decreasing) when profiling the app" Nope, classes are maintained in the Permanent Generation in the memory model, and almost never removed from memory. [see here](https://stackoverflow.com/a/57648657/3124150) – EmmanuelMess Aug 25 '19 at 23:49
  • From your referenced article/docs: "Classes may get collected (unloaded) if the JVM finds they are no longer needed and space may be needed for other classes." The metadata (not the class itself) lives in permanent generation. – Brandon McAnsh Aug 26 '19 at 00:35
0

The value of static variables will persist as long as the class is loaded - it has almost nothing to do with Activity lifecycle (onCreate, ..., onDestroy)

The first time you access a class from code it will get loaded and then it won't go away until there is a reason to unload it.

Android will unload a class if your app gets completely removed from memory - either via a task-killer or when your app is no longer active and memory gets low.

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

Ashok Kumar
  • 1,226
  • 1
  • 10
  • 14
  • "1. the class is unloaded 2. the JVM shuts down 3. the process dies" When do those processes get triggered? – EmmanuelMess Aug 23 '19 at 16:41
  • as mentioned already i.e app gets completely removed from memory - either via a task-killer or when your app is no longer active and memory gets low. – Ashok Kumar Aug 23 '19 at 17:03
  • Do you have any reference that these cases are the only ones that trigger a removal of a static variable from memory in Android apps? – EmmanuelMess Aug 23 '19 at 17:11
0

yes the value which you set in it remains persisted even after the activity closes but not after the application closes.

mahmoudafer
  • 1,139
  • 3
  • 14
  • 30
Hasnain Sabir
  • 200
  • 1
  • 7
0

I'm actually surprised that nobody was able to find a reference. It's right there on Wikipedia:

...a static variable is a variable that has been allocated "statically", meaning that its lifetime (or "extent") is the entire run of the program. This is in contrast to shorter-lived automatic variables, whose storage is stack allocated and deallocated on the call stack; and in contrast to objects, whose storage is dynamically allocated and deallocated in heap memory.

This definition is for general programming languages. But it can be used as a reference to Android. However, in object-oriented programming languages:

In object-oriented programming, there is also the concept of a static member variable, which is a "class variable" of a statically defined class, i.e., a member variable of a given class which is shared across all instances (objects), and is accessible as a member variable of these objects. A class variable of a dynamically defined class, in languages where classes can be defined at run time, is allocated when the class is defined and is not static.

Meaning that in Android, where Java, is used static variables have a lifetime equal to the lifetime of the app, or the instance that is using it, if that static variable is not created at runtime.

Gaurav Mall
  • 2,372
  • 1
  • 17
  • 33
  • We already know what a static variable is, and Wikipedia is not a primary source. "static variables have a lifetime equal to the lifetime of the app, or the instance that is using it" contradicts [this](https://stackoverflow.com/a/42296476/3124150) and [this](https://stackoverflow.com/a/57584390/3124150) answer please reference Android related source. – EmmanuelMess Aug 25 '19 at 11:45
  • You mean that Wikipedia is not a trusted source? – Gaurav Mall Aug 25 '19 at 11:46
  • Wikipedia is not a primary source, primary sources should be referenced. – EmmanuelMess Aug 25 '19 at 13:28
  • Well, I couldn't find anything related to the lifetime of static variables. Only about speed: https://developer.android.com/training/articles/perf-tips – Gaurav Mall Aug 25 '19 at 13:37
-1

A static variable is associated with the lifecycle of class. Once an activity is destroyed than that static variable will also be cleaned up.

If you still want to access that variable you have 2 options:-

  1. override onSaveInstanceState and save the required variables and restore it in onRestoreInstanceState
  2. Store the variables in Application class and access it anywhere anytime.
rimonmostafiz
  • 1,341
  • 1
  • 15
  • 33
Shivam
  • 29
  • 11
  • Please provide references for "A static variable is associated with the lifecycle of class. Once an activity is destroyed than that static variable will also be cleaned up." in the context of Android apps. – EmmanuelMess Aug 22 '19 at 21:33
-1

I recently built a background music for a quiz app and I could control it from any activity because it was in a static class. catch was that the music kept restarting so I had to store the time stamp on onPause and pass to next activity to continue . static class might be destroyed but why not store it's value in sharedPreference before the state changes. like on onDestroy() so you initialize it from anywhere. For the question: 1 save the value in savedInstance state 2 save the values in sharedPreference on onPause or onDestroy of the oncreate state.

Arda Kazancı
  • 8,341
  • 4
  • 28
  • 50
Danazy
  • 19
  • 1
  • 4
-2

Static variables or static blocks are not associated with object. These are class level variable not object associated. If we destroy object, static variable will not destroy which is defined in same class. Static variable initialize once in memory.

so when we close app objects destroy but static variable not destroy. But when we clear app then class destroy and so static variable also. Sometime android kill class due to free memory space in that case static variable destroy.

Abhishek Joshi
  • 361
  • 1
  • 7
  • 17
-2

Once I have developed the application using lots of static vars, The problem with static vars is that once android has low memory it automatically removes the static variable and if your views are connected with static variable it won't show or worse application will crash. I recommend using shared preferences or other methods to store the variables.

problems

  1. If your android memory is low the static variables will be removed from ram and you have to reinitialize them

  2. If your view is attached to the static variables like ArrayList to recycler view it will throw errors like null pointer exceptions for that you have to check balance every time you initialize the view.

  3. The main problem is of your variable is too big like ArrayList with images in it some time it can give out of memory exception

raj kavadia
  • 926
  • 1
  • 10
  • 30