How to Declare Global Variables in Android

Android global variable

You can extend the base android.app.Application class and add member variables like so:

public class MyApplication extends Application {

private String someVariable;

public String getSomeVariable() {
return someVariable;
}

public void setSomeVariable(String someVariable) {
this.someVariable = someVariable;
}
}

In your android manifest you must declare the class implementing android.app.Application (add the android:name=".MyApplication" attribute to the existing application tag):

<application 
android:name=".MyApplication"
android:icon="@drawable/icon"
android:label="@string/app_name">

Then in your activities you can get and set the variable like so:

// set
((MyApplication) this.getApplication()).setSomeVariable("foo");

// get
String s = ((MyApplication) this.getApplication()).getSomeVariable();

Declaring global variables in android

Apart from using Application to create Global Variables, you can create a regular class to hold your variables. Right now, I am using this:

public class GlobalVar {


public String getGlobalVar1() {
return GlobalVar1;
}

public void setGlobalVar1(String GlobalVar1) {
this.GlobalVar1 = GlobalVar1;
}

private String GlobalVar1 = "";

static {
instance = new GlobalVar();

}

private GlobalVar() {
}

public static GlobalVar getInstance() {
return GlobalVar.instance;
}
}

For setting a new value to your GlobalVar1 :

GlobalVar.getInstance().setGlobalVar1(value);

And for getting the value:

GlobalVar.getInstance().getGlobalVar1;

How to implement global variables in extends different from 'Application' and 'Activity'?

You can create a static instance of Globals and access.

public class Globals extends Application {
private static Globals instance;
private List<Float> current = new ArrayList<>();

@Override
public void onCreate() {
instance = this;
super.onCreate();
}

public float getCurrent() {
return current.get(current.size()-1);
}

public void setCurrent(float someVariable) {
this.current.add(someVariable);
}

public static Globals getInstance() {
return instance;
}

public static Context getContext(){
return instance;
// or return instance.getApplicationContext();
}
}

Now anywhere in app you can access the current variable or change the value by

Globals.getInstance().getCurrent();

How to declare global variables in Android?

I wrote this answer back in '09 when Android was relatively new, and there were many not well established areas in Android development. I have added a long addendum at the bottom of this post, addressing some criticism, and detailing a philosophical disagreement I have with the use of Singletons rather than subclassing Application. Read it at your own risk.

ORIGINAL ANSWER:

The more general problem you are encountering is how to save state across several Activities and all parts of your application. A static variable (for instance, a singleton) is a common Java way of achieving this. I have found however, that a more elegant way in Android is to associate your state with the Application context.

As you know, each Activity is also a Context, which is information about its execution environment in the broadest sense. Your application also has a context, and Android guarantees that it will exist as a single instance across your application.

The way to do this is to create your own subclass of android.app.Application, and then specify that class in the application tag in your manifest. Now Android will automatically create an instance of that class and make it available for your entire application. You can access it from any context using the Context.getApplicationContext() method (Activity also provides a method getApplication() which has the exact same effect). Following is an extremely simplified example, with caveats to follow:

class MyApp extends Application {

private String myState;

public String getState(){
return myState;
}
public void setState(String s){
myState = s;
}
}

class Blah extends Activity {

@Override
public void onCreate(Bundle b){
...
MyApp appState = ((MyApp)getApplicationContext());
String state = appState.getState();
...
}
}

This has essentially the same effect as using a static variable or singleton, but integrates quite well into the existing Android framework. Note that this will not work across processes (should your app be one of the rare ones that has multiple processes).

Something to note from the example above; suppose we had instead done something like:

class MyApp extends Application {

private String myState = /* complicated and slow initialization */;

public String getState(){
return myState;
}
}

Now this slow initialization (such as hitting disk, hitting network, anything blocking, etc) will be performed every time Application is instantiated! You may think, well, this is only once for the process and I'll have to pay the cost anyways, right? For instance, as Dianne Hackborn mentions below, it is entirely possible for your process to be instantiated -just- to handle a background broadcast event. If your broadcast processing has no need for this state you have potentially just done a whole series of complicated and slow operations for nothing. Lazy instantiation is the name of the game here. The following is a slightly more complicated way of using Application which makes more sense for anything but the simplest of uses:

class MyApp extends Application {

private MyStateManager myStateManager = new MyStateManager();

public MyStateManager getStateManager(){
return myStateManager ;
}
}

class MyStateManager {

MyStateManager() {
/* this should be fast */
}

String getState() {
/* if necessary, perform blocking calls here */
/* make sure to deal with any multithreading/synchronicity issues */

...

return state;
}
}

class Blah extends Activity {

@Override
public void onCreate(Bundle b){
...
MyStateManager stateManager = ((MyApp)getApplicationContext()).getStateManager();
String state = stateManager.getState();
...
}
}

While I prefer Application subclassing to using singletons here as the more elegant solution, I would rather developers use singletons if really necessary over not thinking at all through the performance and multithreading implications of associating state with the Application subclass.

NOTE 1: Also as anticafe commented, in order to correctly tie your Application override to your application a tag is necessary in the manifest file. Again, see the Android docs for more info. An example:

<application
android:name="my.application.MyApp"
android:icon="..."
android:label="...">
</application>

NOTE 2: user608578 asks below how this works with managing native object lifecycles. I am not up to speed on using native code with Android in the slightest, and I am not qualified to answer how that would interact with my solution. If someone does have an answer to this, I am willing to credit them and put the information in this post for maximum visibility.

ADDENDUM:

As some people have noted, this is not a solution for persistent state, something I perhaps should have emphasized more in the original answer. I.e. this is not meant to be a solution for saving user or other information that is meant to be persisted across application lifetimes. Thus, I consider most criticism below related to Applications being killed at any time, etc..., moot, as anything that ever needed to be persisted to disk should not be stored through an Application subclass. It is meant to be a solution for storing temporary, easily re-creatable application state (whether a user is logged in for example) and components which are single instance (application network manager for example) (NOT singleton!) in nature.

Dayerman has been kind enough to point out an interesting conversation with Reto Meier and Dianne Hackborn in which use of Application subclasses is discouraged in favor of Singleton patterns. Somatik also pointed out something of this nature earlier, although I didn't see it at the time. Because of Reto and Dianne's roles in maintaining the Android platform, I cannot in good faith recommend ignoring their advice. What they say, goes. I do wish to disagree with the opinions, expressed with regards to preferring Singleton over Application subclasses. In my disagreement I will be making use of concepts best explained in this StackExchange explanation of the Singleton design pattern, so that I do not have to define terms in this answer. I highly encourage skimming the link before continuing. Point by point:

Dianne states, "There is no reason to subclass from Application. It is no different than making a singleton..." This first claim is incorrect. There are two main reasons for this. 1) The Application class provides a better lifetime guarantee for an application developer; it is guaranteed to have the lifetime of the application. A singleton is not EXPLICITLY tied to the lifetime of the application (although it is effectively). This may be a non-issue for your average application developer, but I would argue this is exactly the type of contract the Android API should be offering, and it provides much more flexibility to the Android system as well, by minimizing the lifetime of associated data. 2) The Application class provides the application developer with a single instance holder for state, which is very different from a Singleton holder of state. For a list of the differences, see the Singleton explanation link above.

Dianne continues, "...just likely to be something you regret in the future as you find your Application object becoming this big tangled mess of what should be independent application logic." This is certainly not incorrect, but this is not a reason for choosing Singleton over Application subclass. None of Diane's arguments provide a reason that using a Singleton is better than an Application subclass, all she attempts to establish is that using a Singleton is no worse than an Application subclass, which I believe is false.

She continues, "And this leads more naturally to how you should be managing these things -- initializing them on demand." This ignores the fact that there is no reason you cannot initialize on demand using an Application subclass as well. Again there is no difference.

Dianne ends with "The framework itself has tons and tons of singletons for all the little shared data it maintains for the app, such as caches of loaded resources, pools of objects, etc. It works great." I am not arguing that using Singletons cannot work fine or are not a legitimate alternative. I am arguing that Singletons do not provide as strong a contract with the Android system as using an Application subclass, and further that using Singletons generally points to inflexible design, which is not easily modified, and leads to many problems down the road. IMHO, the strong contract the Android API offers to developer applications is one of the most appealing and pleasing aspects of programming with Android, and helped lead to early developer adoption which drove the Android platform to the success it has today. Suggesting using Singletons is implicitly moving away from a strong API contract, and in my opinion, weakens the Android framework.

Dianne has commented below as well, mentioning an additional downside to using Application subclasses, they may encourage or make it easier to write less performance code. This is very true, and I have edited this answer to emphasize the importance of considering perf here, and taking the correct approach if you're using Application subclassing. As Dianne states, it is important to remember that your Application class will be instantiated every time your process is loaded (could be multiple times at once if your application runs in multiple processes!) even if the process is only being loaded for a background broadcast event. It is therefore important to use the Application class more as a repository for pointers to shared components of your application rather than as a place to do any processing!

I leave you with the following list of downsides to Singletons, as stolen from the earlier StackExchange link:

  • Inability to use abstract or interface classes;
  • Inability to subclass;
  • High coupling across the application (difficult to modify);
  • Difficult to test (can't fake/mock in unit tests);
  • Difficult to parallelize in the case of mutable state (requires extensive locking);

and add my own:

  • Unclear and unmanageable lifetime contract unsuited for Android (or most other) development;

How to create a global variable in android?

You can create the global variable in android by declaring them in the class which extend the Application class.

Something like this.

class MyAppApplication extends Application {

private String mGlobalVarValue;

public String getGlobalVarValue() {
return mGlobalVarValue;
}

public void setGlobalVarValue(String str) {
mGlobalVarValue = str;
}
}

MainActivity.java

class MainActivity extends Activity {
@Override
public void onCreate(Bundle b){
...
MyAppApplication mApp = ((MyAppApplication)getApplicationContext());
String globalVarValue = mApp.getGlobalVarValue();
...
}
}

Update

This hold the value until your application is not destroyed. If you want to keep your values save even after your application instance destroy
then you can use the SharedPreferences best way to do this.

Learn about the SharedPrefernces from here : http://developer.android.com/reference/android/content/SharedPreferences.html

Android Studio - Kotlin - Global Variables and Functions

Kotlin is much simpler. Don't create a class but an object:

object GlobalStuff {
var mainNavState: Int = 0
}

And use it like this from another class:

GlobalStuff.mainNavState = 1
val x = GlobalStuff.mainNavState

Use global variables in an Adaptor Android Studio

I don't know if you have done this somewhere else in your code, but the code snippet that you provided, the problem lies in the fact that you haven't actually created the 'selectedPlayer' Arraylist. It can be checked if you are getting the nullPointerException.

although, I would suggest, rather than creating a globalState class like this, Make a class That would hold context Independent information, and declare static member variables, and methods. So that you do not have to instantiate the class for using. Since you are going to use selectedPlayer as a global variable anyway, its better to make it static, to prevent duplicate instantiation.

As for the solution to your problem for this particular case, just doing

 private ArrayList<Integer> selectedPlayer = new ArrayList<>();

should be enough.



Related Topics



Leave a reply



Submit