6

I have a multi activity application and save data in the main menu activity that is used by many of the other activities.

One of my variables in the Main activity might be this

static double targetAngle = 45;

I might call that variable from another activity like this

diff = Main.targetAngle - angle;

or I might set it like this

Main.targetAngle = angle;

From this reference, http://developer.android.com/guide/faq/framework.html This seems like a correct way to pass data. But there is always talk about activities being killed by the OS at any time.

My question is, is this safe or not?

As an alternative, I have at the suggestion of SO members, a Class called Helper that has some functions that are used in every activity which also have some static data. For example, the Helper Class has this data followed by my functions

public class Helper {
static double[] filter1 = new double[]{0,0,0,0,0};
static double[] filter2 = new double[]{0,0,0,0,0};
static double cog = 0;
    ...
   various functions....
}

I could save my shared variables in that helper class if that would be better. That class is called once a second and if it is ever killed, I am dead and really need to rethink things. I should mention that I have had no issues with what I am doing but one of my users is having his Nexus-7 crash and we don't know why so I was thinking he might have more applications running than I do, thus my question.

I should also mention that if the user exits the application, I have saved any variables that need to be saved in files on the SD card so they can be re-loaded. In other words, the loss of data when the application is killed is not an issue. My question is only if my main activity was killed when the application was still alive.

Allen Edwards
  • 1,488
  • 1
  • 27
  • 44
  • Activity classes themselves don't get destroyed by the operating system - instances of classes do. So while the instance of your activity may get the onDestroy callback and garbage collected, the public static variables of that Activity class will still persist. – selbie Nov 25 '13 at 01:04
  • **"My question is, is this safe or not?"** - NO! Never create public static fields (or methods) in an `Activity`. Always use helpers or pass data as Intent extras between Activities. – Squonk Nov 25 '13 at 01:05
  • I think @selbie is saying it is OK and Squonk is saying it is not. That is curious. – Allen Edwards Nov 25 '13 at 01:16
  • 1
    @AllenEdwards : The Android `Activity` class is a special case class (as are some of the other main Android application components) and not just a regular Java class. It is best practice that an `Activity` should be considered self-contained and not expose public fields or methods (static or otherwise). Using inheritance is fine but at that point you don't need the static modifier. My point is that a developer shouldn't adopt an approach of exposing public and/or static fields/methods in an Activity - it may work in some cases but push it too far and your app will crash and burn. – Squonk Nov 25 '13 at 01:26
  • Based on my experience, Squonk is right. It is possible that the static variables on `Activity` become `null` when garbage collection comes, thus resulting `NullPointerException` and does crash your app. – Andrew T. Nov 25 '13 at 01:26
  • Oh boy. I have 687 instances of references to static variables in the Main activity within the various activities of my application. If I have to move them, do I put them in my Helper Class? By the way, that won't be easy to move and without making a mistake. – Allen Edwards Nov 25 '13 at 01:35
  • @AllenEdwards : Yes, I would copy the static fields from the main Activity into the helper then comment them out of the Activity (you can always go back if you need to). Do a Search / Replace on Main.targetAngle replacing with Helper.targetAngle (for example). Over the years I've had to do this sort of thing - it's a PITA but I strongly recommend you do it to avoid future problems. – Squonk Nov 25 '13 at 01:50
  • One good way of testing whether your app can kindle this sort of thing is. Go to some screen where the static variable is set. Go home. Kill the process. Come back to the app. Your activity will resume but the static variable will be null. – yarian Nov 25 '13 at 02:04
  • @yarian Perhaps I don't understand as if I go home and kill the app, when I start the app again, it starts over as expected. When you say "Kill the Process" are you talking about something other than killing the application in settings->application manager-> (app) -> Force Stop. – Allen Edwards Nov 25 '13 at 02:53
  • @Squonk Just a point of clarification, if the user leaves the app and re-enters it, all the variables are re-read off a file by the main page. I an only concerned about things going away while the app is running and at least one activity of the app is in the foreground. My app dominates the device when being run, it is not something you go in and out of. Plus, all the variables are re-read out of the SD care whenever the main page is started. – Allen Edwards Nov 25 '13 at 02:59
  • @Squonk Nice suggestion on the search and replace. That makes the task, if necessary, much easier. I would just replace all the Main. with Helper. – Allen Edwards Nov 25 '13 at 03:09
  • @AllenEdwards : WRT Search / Replace...yes, the right tools make things easier. :) As for your explanation of how your app works, I'm simply trying to explain that adopting the approach of "shared" variables between an Activity and another Android app component may lead you into trouble in future apps which don't work the same way. Using helpers (either instance types or singletons) is a better approach or if you really want something with a full life-cycle of your app then extend the `Application` class (although only do that if you have a really good reason to do so). – Squonk Nov 25 '13 at 03:56
  • @Squonk Thanks for all your help. I am left with the question of how do I know that my Helper Class will not suffer the same fate and get destroyed by the OS. Makes me wonder why you can even call a static variable like Main.targetAngle if they are not safe. Seems strange that it is allowed but in some way not safe. – Allen Edwards Nov 25 '13 at 04:03
  • @AllenEdwards : Try not to "over think" things. It's true the OS will recycle app components when resources are needed but it's an efficient and safe system. The OS will focus on other apps recently used before the current app with a foreground Activity etc - the one with last known use date/time will be the first target. As long as your app is running and any objects have references from other objects the system will leave them alone. As for static variables being allowed but not safe - probably just the Java heritage - it's OK for normal Java classes but Activity is a special case. – Squonk Nov 25 '13 at 05:16
  • @Squonk Thank you for your time to clearly explain this. Do you want to write it up as an answer so I can check it off as solved? – Allen Edwards Nov 25 '13 at 05:56
  • How would it even work that the OS can "reset" or "change" (??) a class static variable? What does that even mean? How could it happen? A static is just a global. – Fattie Jun 19 '22 at 19:57

2 Answers2

2

My thanks to selbie and squonk for answers in the comments. Lacking an official answer from either I post my own as I want to close this out.

What I conclude is that per this post Using static variables in Android, the static variables themselves are not destroyed and what I am doing is safe.
This post, Clearing Static data onDestroy() states that "The value of static variables will persist as long as the class is loaded...The only reason ... that Android will unload a class is that your app gets completely removed from memory"

However, it may not be good practice as pointed out by squonk. Using a Class that is not an Activity to host static global variables and common functions may be better practice and is easier to maintain and generally cleaner. I will be moving in that direction as it has other advantages as well.

In either case, it is clear that when the application is destroyed, the variables will be re-initialized and needs to be reset manually. In my case, I store data on the SD card in files, which is one of several ways to save data.

I found the above links with a new Google search. Obviously I should have done a search with that wording earlier but none of my searches returned useful results, mostly finding the singleton vs extension of application debate.

Community
  • 1
  • 1
Allen Edwards
  • 1,488
  • 1
  • 27
  • 44
-1

static variable cannot use over through Activity. As you said, they become initial value when you called again from another activity even you assign value.

Use SharedPreference or pass value with Bundle.

Thein
  • 3,940
  • 2
  • 30
  • 34
  • I did not say they become initial again when called again from another activity and in fact they do not. They maintain their value. As I said, the application works and has worked for over a year. I am just wondering if there is some condition where it might not but I have not seen that condition myself. – Allen Edwards Nov 25 '13 at 01:14
  • I mean using Helper class might be null in another activity if you used as passing value. Sorry, if I am wrong. But in my case, I faced like that so I used `SharedPreference`. Hope this post helpful for you. http://stackoverflow.com/questions/9541688/static-variable-null-when-returning-to-the-app – Thein Nov 25 '13 at 01:40