2

I just discovered an apparent gap in my Android/Java understanding. In particular, it appears that static class variables are preserved between different invocations of my app.

Is this to be expected?.

I did a diligent search of StackOverflow and elsewhere but I can find no mention of this. As an experiment, I tried the following code in my initial Activity:

static int MyCount;
...
public void onCreate(Bundle savedInstanceState) {
Log.d( "MYAPP", "MyCount="+MyCount );
MyCount++;
...

If I exit the app (via finish()) and restart it, MyCount keeps getting incremented. This surprised me. Is this an expected behavior?
(and please, no lectures on the evils of static variables :)

DontPanic
  • 2,164
  • 5
  • 29
  • 56
  • No static variables should not be shared between processes. I would expect that the app is not actually shutting down. I believe that android does not actually terminate applications unless you force it to. – Neilos Mar 18 '15 at 15:42

3 Answers3

2

No, static variables are not preserved between multiple app instances.

This is most likely because you didn't completely close your app (via settings->stop process or a similar method) but instead your app was simply running in the background and preserving the value of the static variable.

bwegs
  • 3,769
  • 2
  • 30
  • 33
  • Hmmm. I didn't get so aggressive as to kill the app via Aplications Manager but I *assumed* that finish() would stop it. Am I incorrect? – DontPanic Mar 18 '15 at 15:48
  • @DontPanic I'm afraid that's not the case, see http://stackoverflow.com/questions/4594996/activity-finish-called-but-activity-stays-loaded-in-memory – bwegs Mar 18 '15 at 15:56
2

Is this to be expected?.

That depends entirely upon what you mean by "invocations of my app".

Let's suppose that you have a single-activity application. You then manually execute the following pseudo-code:

for
  click on app's icon in home screen launcher
  click BACK to destroy that activity and return to the home screen launcher
while not tired of doing this yet

Assuming no significant delays in loop processing, you will maintain one process for the entirety of the loop, and therefore your static data members will still exist.

The lifetime of static data members is the lifetime of the Java process, and you do not control when your process goes away.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Yes, the pseudo code above is exactly what I tried, but variable still *appears* to be preserved. I *assumed* that when the app exits ("Back", etc.), the process would exit. Maybe not so? – DontPanic Mar 18 '15 at 15:54
  • interestingly, I looked at the PID in LogCat, and multiple starts of the same app have the same PID. So I guess that explains it, but why the shared PID is still a mystery to me. – DontPanic Mar 18 '15 at 16:06
  • @DontPanic: "I assumed that when the app exits ("Back", etc.), the process would exit. Maybe not so?" -- correct. BACK has no immediate impact upon your process. "why the shared PID is still a mystery to me" -- I linked to the documentation that covers this in my answer. – CommonsWare Mar 18 '15 at 16:49
  • Thank you for a very authoritative answer. And thanks to all the other responders! – DontPanic Mar 19 '15 at 14:09
0

The lifetime of a static is limited to the lifetime of the JVM associated with the particular class loader that loaded the first instance of the class.

So no, it would not be shared across separate processes.

It's worth pointing out that int is an atomic type in Java, but long might not be. Do bear that in mind when considering the thread safety of onCreate.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483