Using Global Variables

2019-08-15 14:53发布

问题:

I know this question has been asked a million times because I have done some research and have found many threads on this. I have tried to use the answers in those threads but I am having a bit of trouble.

I am looking to set a few variables that I can use across all of my activities.

I created a GlobalVariables.java class which looks like the following (the value in there is just for testing purposes as of now):

import android.app.Application;

public class GlobalVariables extends Application {

int holeAmount;

public int getHoles(){
    return holeAmount;
  }
  public void setHoles(String s){
    holeAmount = 30;
  }

}

in my main activity where everything is happening I have the following:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    GlobalVariables global = ((GlobalVariables)getApplicationContext());
    int totalHoles = global.getHoles();

and on the "GlobalVariables global = ..." line I am getting the following error:

Multiple markers at this line
- GlobalVariables cannot be resolved 
 to a type
- GlobalVariables cannot be resolved 
 to a type

I tried to follow the instructions here but clearly I am doing something incorrectly. > How to declare global variables in Android?

Any help would be greatly appreciated!

Thanks!



SECOND ATTEMPT:

EasyPar.java (Errors @ EasyParHelperActivity)

package com.movi.easypar;

import java.text.DateFormat;
import java.util.Date;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

public class EasyPar extends Activity implements OnClickListener {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

(initialize all my buttons and textviews)
}

public void someMethod() {
    EasyParHelperActivity.helper.setHoles(30);
    int holes = EasyParHelperActivity.helper.getHoles();
}

(the rest of my button functions, etc.)

EasyParHelperActivity (No Errors)

package com.movi.easypar;

import android.app.Application;

public class EasyParHelperActivity extends Application {

public static EasyParHelper helper = new EasyParHelper();

}

EasyParHelper.java (No Errors)

package com.movi.easypar;

public class EasyParHelper {

private int holeAmount = 0;

public int getHoles() {
    return holeAmount;
}

public void setHoles(int holes) {
    holeAmount = holes;
}
}

All i want is for the user to be able to click a button "18" or "9" on the first screen, and for the application to be able to use that value other times throughout whatever it does. So I need to set it in screen 1, and in screen 2 i need to retrieve that value.

回答1:

Create a 'helper' class as follows...

package com.my.application

public class MyAppHelper {

    private int holeAmount = 0;

    public int getHoles() {
        return holeAmount;
    }

    public void setHoles(int holes) {
        holeAmount = holes;
    }
}

Then for your Application class do the following...

package com.my.application

public class MyApplication extends Application {

    public static MyAppHelper helper = new MyAppHelper();

}

To get access to the get/set methods in the helper you can simply call...

package com.my.application

public class MyActivity extends Activity {

    // Normal onCreate(...) etc here

    public void someMethod() {
        MyApplication.helper.setHoles(30);
        int holes = MyApplication.helper.getHoles();
    }
}


回答2:

You need to import GlobalVariables. Also you need to put the full class name of GlobalVariables in application's name attribute in manifest as described here: http://developer.android.com/guide/topics/manifest/application-element.html#nm



回答3:

First things first...

You should to deeply consider if and why you might need a global variable. Global variables should only be used as a last resort. Furthermore if you do end up needing to use global variable(s) you need to document them to death because make no mistake, if your app gets complex you WILL lose track of one or more of them. Tracking them down is a severe PIA!!!

It has been my experience that almost 99% of the time global variables are used it is because of programmer laziness and whatever they were trying to achieve could have been done in a way that used programming best practices.

Here is an example: https://groups.google.com/forum/#!topic/android-developers/yfI89IElhs8

Without knowing more about what you are attempting to pass between your classes, I cannot offer any other advice other than what I've provided. However, I am fairly POSITIVE that you can achieve what you are looking for without using any global variables.



回答4:

What if you do

GlobalVariables global = ((GlobalVariables)getApplication());

From docs it's not clear you receive actual application object from getApplicationContext() or some other implementation. And from code it definitely does not appear so.

For your purposes, however you want to get your Application object which would be your GlobalVariables. And make sure that it's properly registered in manifest.


Also just to make sure, that you have

package com.my.application;

At the beginning of GlobalVariables, don't you? Don't see it in your snippet.



回答5:

What I have set up, and that has been working out for me is to just create a public class and then initialize it with the context from whatever class had called it. I found this at this link. This actually let me get access to things like the system services. I then went ahead and defined some class variables that let me call in and out of the class. But to actually handle the storage of the variables, I employed SharedPrefrences. The nice thing about this setup was that I didn't have to keep setting up the code for the shared prefrences before I accessed each variable. I just did it through the public class. Now keep in mind, I'm a complete novice at this stuff, and I'm not sure that this is the best approach, or even if this should be done in this way at all. But I decided to share what I've been doing all the same. So here's some code:

    package com.example.someapp;

    import android.app.PendingIntent;
    import android.content.Context;
    import android.content.Intent;
    import android.content.SharedPreferences;

    public class GlobalThing {

Context me;
SharedPreferences appdata;

public GlobalThing(Context me) {
    this.me = me;
    appdata = me.getApplicationContext().getSharedPreferences(
            "ApllicationData", 0);
}

public boolean alarmRunning() {
    boolean b;
    Intent i = new Intent(me, AlarmThing.class);
    b = (PendingIntent.getBroadcast(me, 0, i, PendingIntent.FLAG_NO_CREATE) != null);
    if (b) {
        return true;
    } else {
        return false;
    }
}

public void timeIn(long time){
    SharedPreferences.Editor timeVar = appdata.edit();
    timeVar.putLong("time delay", time);
    timeVar.commit();
}
public long timeOut(){
    return appdata.getLong("time delay", 0);
}
     }

Above is the actual global class. This doesn't get declared in the manifest or anything.

Then to access the variables in this class I would code something like this in an activity:

      public class SmokeInterface extends Activity implements OnClickListener {

GlobalThing gt;
boolean bool;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_smoke_interface);
          gt = new GlobalThing(this);
                setalarm();
      }

And access the variables like this:

        private void setAlarm() {
    bool = gt.alarmRunning();
    if (bool) {
        Toast.makeText(this, "Alarm is already running.",
                Toast.LENGTH_SHORT).show();
    } else {
        AlarmManager m = (AlarmManager) getSystemService(ALARM_SERVICE);
        Intent i = new Intent(this, AlarmThing.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i,
                PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar time = Calendar.getInstance();
        time.setTimeInMillis(System.currentTimeMillis());
        time.add(Calendar.SECOND, 10);
        m.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pi);
    }
}

or this...

    gt.timeIn(60);//write time in (long) to shared prefrences
    long l = gt.timeOut();//read time out (long) from shared prefrences