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
Related
I have an application whose different activities need an access to many values that could be stored in a global variable in order to know which views should be visible and/or enabled. It is a kind of views-visibility variable. The thing is that I want to save all those visibility values in the different attributes of this object and I want this object to stay safety alive for all the application lifecycle, then is when I came down to global variables.
I've read different options to do this:
1) Creating this object in the main activity using Singleton pattern.
2) Creating this object as an static class and fulfilling the values in main activity.
3) Creating this object as a calss extending Application in the main activity.
Then the object is supposed to be called and accessed from each activity of the application. But, is any of these options correct and efficient to access global variables? Is it recommended to avoid using global variables?
Thank you
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).
I'm taking an android class now, so I am somewhat new to android app development.
My first assumption for a Base Activity is that it's Global Variables and it's values would be available to all activities. I have found that it is available to my Main Activity, but not any activities after that.
In the Base Activity I am storing an ArrayList of Objects. I also load data from an xml in there that adds objects to the arrayList. Once in the Main Activity I still have access to that arrayList and it's values. I use it to fill a list. But when I go to the next activity, it knows about the arrayList but thinks it is empty.
Do I need to create methods in the base activity to retrieve the arrayList and to add objects to the array list?
Any help would be appreciated.
Thank you,
Michelle
Global variables need to be declared static. Then they would be accessible from any class. Example:
public class Globals {
public static String myString;
}
Any class can read/write the myString like this:
Globals.myString = "foo";
or
String bar = Globals.myString;
From experience I believe the variables of one activity is only avaliable to the other while the activity is active, which means between onCreate and onDestroy, other then that you will probably get a null pointer exception, what you really should be doing is sending the data, or arrays, along with the intent to the other activity.
I dont think you should be calling on other activities variables, although it is possible as stated above. I believe when the activity has had it's onDestroy method called the objects in the activity are destroyed to and are removed from memory. Destroying anything that they held.
What is this base activity? Does it just extend activity? And then MainActivity is extending Activity as well? Only one activity is usable at any one time, if your doing what I think your doing you should have a service which can provide you with everything over the cycle of the application, just remember to stop it when your done with it.
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
I have a bug in my code that made me think I don't fully understand the Android Lifecycle. Yes, I have read all the docs and looked at the diagrams, but they seem to talk only about when to save data, when the activity may loose focus or get killed. However, my question is if I don't need to save state, what happens to the variables & their stored values? I expected them to be destroyed to, but a bug in my code seems to indicate otherwise.
In my case here is what happened. I have an activity that launches a custom view (no xml, I just draw bitmaps on the screen in my custom view). The only variable I currently have in my activity is just a variable for my view: GameView gameView;
Now in my view, I declare several bitmaps, simple int and float variable to deal with drawing and on touch events and I have one array of objects that contain small bitmaps, coordinates of each objects and a few other things. One of the variables in my class for this object, is a static variable that represents the current count of how many objects their are. I did it this way, so the instantiation of the objects causes it to track how man objects their are, instead of tracking this outside the object's class.
I expected the static variable to stay the same value across all objects, but I also expected this variable to be destroyed along with all the other variables and objects of that Activity's view once onDestroyed was called for that Activity. However, that doesn't seem to happen. When this Activity is launched again, this static variable still contains its previous value from its last run - even though onDestroyed was called.
Now my question is NOT how to fix this (I can write code differently to fix this bug), but I would like to understand why this happens with this static variable, since it isn't global to the whole application, it only exists inside that Activity's view? Also, this makes me wonder about the rest of the variables in that view - are they destroyed and their memory released or at least their values no longer available the next time the activity is called or do I need to do this myself - even though I didn't need to save any of this state data?
Thanks for any insight into this.
onDestroy is an instance method and any memory it releases (or allows the garbage collector to release) will be of the corresponding instance. Activities are not singleton; there can be more than one instance of an Activity.
Static variables are class variables and are accesible to all instances of that class. They are initialized when the class is loaded, not when each instance of the class is created.
Please see Understanding Instance and Class members for more info. An excerpt:
Sometimes, you want to have variables
that are common to all objects. This
is accomplished with the static
modifier. Fields that have the static
modifier in their declaration are
called static fields or class
variables. They are associated with
the class, rather than with any
object. Every instance of the class
shares a class variable, which is in
one fixed location in memory. Any
object can change the value of a class
variable, but class variables can also
be manipulated without creating an
instance of the class.