1

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!

Community
  • 1
  • 1
Markstar
  • 345
  • 4
  • 17

5 Answers5

3

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.

laalto
  • 137,703
  • 64
  • 254
  • 280
  • Yes, I got the impression that avoiding global variables is the best practice, but I'm running into serious troubles when using Fragments and switching layouts, so as a noob I have not yet found a way around that other than using global variables. But the lifecycle seems like a valid reason, even though I don't fully understand it (because, well, don't I have to save my variables anyways when going onPause, etc.?). Regarding the unnecessary dependency: Don't I always have to load the MainActivity when using my apps? – Markstar Jan 20 '14 at 14:25
  • With fragmens use the arguments mechanism and state saving. MainActivity is not necessarily loaded by the class loader: classes are only loaded when referenced. Your app can have more than one entry point activity. – laalto Jan 20 '14 at 15:12
  • Ah, interesting. So I will use the Application class and hope to reduce the amount of variables there. – Markstar Jan 20 '14 at 15:48
1

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

Gaurav Gupta
  • 4,228
  • 1
  • 31
  • 59
  • Yes, I realize that, but don't see how this is an advantage compared to declaring it in the MainActivity. – Markstar Jan 20 '14 at 14:21
  • Hmm, it seems I'm already suffering from _Singletonitis_ ... the main purpose of my global variables right now is to keep track of the loaded fragments and their content. I realize that there should be a better way, but I'm still new at this and admit I'm a bit overwhelmed by all the thing to consider when building the UI. – Markstar Jan 20 '14 at 15:49
  • @Markstar I think you can query `FragmentManager` to get the fragment by `id`, If fragment will be loaded then you will get `Object` otherwise not. Not so much sure about solution, but holding on Activity just because you need to keep track of `fragment state` may be an expensive idea. If this is provided by framework, then why not utilize that. Please, give it a try and let me know too. – Gaurav Gupta Jan 21 '14 at 06:23
  • The problem is not (at least no **anymore**) that I can't find my Fragments, but that I need to keep track of where I am so that the Fragments don't execute code that they are not supposed to (e.g. I do something in one Fragment, switch the orientation, continue to do stuff or go back and switch back to the original orientation. Then the app crashes because there are Fragments still there in the old orientation). I realize that there **must** be a more elegant solution for this, but I'm still a noob and don't yet know what this solution might look like. – Markstar Jan 21 '14 at 14:59
0

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...

Gopal Gopi
  • 11,317
  • 1
  • 27
  • 43
0

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..

cristianchiess
  • 477
  • 5
  • 11
  • I _think_ I understand that you obviously want to limit the amount of information that is passed between Activities (like in your example you only need the return code and the added products). But I don't see how that goes against using the MainActivity as a place to hold global variables. – Markstar Jan 20 '14 at 14:34
0

You can use Application's class (OS save variable in memory while app not destroy) or SharedPreferences (OS save variable to file permanent).

Tapa Save
  • 4,276
  • 4
  • 30
  • 52