I have defined a global variable inside an activity, this variable changes depending on the button user has pressed.
If I go outside of my app UI and come back by holding the home button which shows the list of recent apps, then my variable keeps its state, but if I run my app again by pressing the app aicon the variable state is gone.
Is there a way to keep the state of the variable?
You can save the variable's value during the onSaveInstanceState() callback. Then you use the "icicle" parameter that is passed to and onCreate() to restore the value. You might be interested in reading Managing the Activity Lifecycle.
Also note that Java has class variables and member variables but not global variables.
As what #Code-Guru says, you could use onSaveInstanceState() to save variable's value.
Another simple way to do is to create a static member in a static class to store the variable. The static class exists as long as the app is in the memory.
You can consider to use shared preferences This class is used to store and retrieve simple data.
Related
I have an activity that consists mainly of a viewpager. The user can open new versions of that activity with different intents, thus making the data in the viewpagers different. Problem is when I access static variables in other classes from the main activity type, it seems as if it is editing variable values in all open versions of the activity. If I finish() the top activity,the data in the original activity has changed to that of the child activity. What is a way to keep references to static variables with only the current activity?
Thanks!
What is a way to keep references to static variables with only the current activity?
Quite simply - you can't.
In Java when you declare a variable as static in the main body of the class, it is a 'class variable'. This means that all instances of that class share only one variable between them. Consequentially (as you've already found out) changing the value in any instance of the class will change the value for all instances as there is only one 'copy' of the variable.
A golden rule in Android is to NEVER use static variables or methods in Activities.
There are two reasons for this - if your Activity is only ever extended within your ouwn code, then having a static variable or method is pointless and (as you've discovered), it's counter-productive.
The second reason is that static is often used with the public modifier in order to allow an 'all-areas' access to variables and/or methods regardless of whether an actual instance of any given class exists or not - in the case of the class being an Activity, this is a VERY dangerous game to play because of the life-cycle of Activities.
If you have a 'base' Activity which you want to start various instances of but want a common variable they all need to have access to, then simply declare it as...
protected Object myVariable;
...replacing Object with whatever type of variable you want.
Each Activity will get there own instance of myVariable and can change its value without affecting any other instance of the same Activity class.
See the following for Java Class Variables
I'm new to Android (and Java) and was trying to find out where to store my global variables that I need in my various Activities, Fragments, etc. so I can easily access them, as well as saving and restoring them when the app is paused (a process that not yet fully understand, but that is not my question).
So the general consensus seems to be to use Singletons by extending Application (like described here).
Now that I played around some more I was wondering what is the reason against declaring variables in the main activity (e.g.final static int myVariable) and then accessing the variable trough MainActivity.myVariable? What is the downside?
Thank you in advance!
First, consider to design your app without needing global variables in the first place. Using global state variables might seem like an easy solution at first, but will complicate testing and maintenance later.
If you absolutely must, the application class is the correct place because it's lifecycle is your application's lifecycle. You can also use regular member variables instead of statics.
If you store variables in an activity class as static variables, the downsides include but are not limited to:
Loading another activity class needs to load all the code in the main activity as well.
Unnecessary dependency from activity to another, creating increased coupling.
statics are harder to mock/inject for example in a testing setup. A thin application object with member vars is easier to mock.
You can make a class that is subclass of Application, and scope of this class will be application wide, so you can access variable globally ( across the activities/fragment)
here you will get related info
there is no downside declaring your global variable as static unless the variable is bound to Context...
it is bad way to maintain static reference for Context (like Activity, Service), Views, Drawables and application Resources...
and some one said in SO (I didn't remember), Android will clear static memory in low memory situations...
For example if you are in "FirstActivity" that calls "SecondActivity", using startActivityForResult, to add a Product do a list, in "SecondActivity" you can CANCEL or ADD this product, if you ADDED it you whant to refresh the Product's list in "FirstActivity" so in "SecondActivity" you can use a "private static final int ADDED = 1" and a "private static final int CANCELED = 2" and pass one of this attributes in the setResult's method of "SecondActivity", before call the finish method, in FirstActivity's "onActivityResult" method you can verify if the "resultCode" is "SecondActivity.CANCELED" or "SecondActivity.ADD" and performe the list's refresh or not.
Just an example..
You can use Application's class (OS save variable in memory while app not destroy) or SharedPreferences (OS save variable to file permanent).
In my Android project I have an Activity and a Widget (Broadcast Receiver). Both have a simple button. When either of the buttons is clicked, the same action should be executed:
First of all, a Boolean variable should be set to it's opposite value (true to false, false to true). This Boolean should be stored independently from both the Activity's and the Receiver's life cycles.
Then, depending on the Boolean's old state, one of two methods should be executed to query a SQLite Database.
I need something like a Singleton Activity, which has its own Shared Preferences and methods and can be called from various Activities / Receivers.
What would be the best way to implement something like this?
Doesn't sound like anything you want to do requires an activity. I would just write a POJO singleton with a private constructor and a static getInstance() method that returns a reference to a private static instance of the class itself, after initializing it if needed.
Then you can have an instance method that toggles the variable and fires off an AsycTask or whatever to do your query. The state of the boolean can be stored in a private instance variable, or persisted to SharedPreferences depending on how long it needs to be retained.
When an app have been put into the background and later resumes to an activity, is it possible that static class variables set in another Activity could have been reset by the garbage collector and have got the value set to zero?
I use a couple of public static int variables in my main Activity and use them as global variables in various other Activities. I have received a crash report in the developer console from Android Market where the only explanation I can find is that the app resumes to an Activity which uses the value of a public static int variable in another class, but the value has (mysteriously?) become zero. I know that it was set to something else when the app first started. Is this at all possible?
If my suspicion is correct, what is the recommended way to preserve the values of the global variables when an app is put in to background? Save them in SharedPreferences in OnPause() or use onSaveInstanceState or something else?
When an app have been put into the background and later resumes to an activity, is it possible that static class variables set in another Activity could have been reset by the garbage collector and have got the value set to zero?
It would not be "reset by the garbage collector". However, the process may have been terminated by Android, to free up memory for other applications.
what is the recommended way to preserve the values of the global variables when an app is put in to background?
Static data members should only be a cache. Data you want to retain regardless of what happens (e.g., process being terminated) needs to go in some persistent store, such as a flat file, SharedPreferences, or database. onPause() is a likely time to arrange to persist that data, as any time after that, your process could be terminated without notice.
Be careful with static variables. Follow the link for an explanation concerning Singleton (which also use a static variable to maintain state): https://stackoverflow.com/a/9004638/1127492
You can save this values on SQLite on method onDestroy in activity or another method with response to exit.
I have an Activity that needs to save a single primitive (not an object) that is used to alter the UI in onResume(). I store this primitive in a separate class with a static variable reference. I realize I could use SharedPreferences to store this variable, however, what I want to know is if using the static variable to hold this primitive could potentially create problems.
Thanks to everyone for their input.
static variables holds value till application is running, once application get destroy all static variables loses their references (non long term) while share preference holds the value even if application get destroy, so consistency is more in share preference
now its upto you whether you want the variable value consistent or not
I DISAGREE with static variable loses their references. Even when activities that hold static variable values destroy, other activities can still access them. For example, a bitmap variable from another activity that is closed completely, can be used by another activity