1

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.

Community
  • 1
  • 1
Rob
  • 1,162
  • 2
  • 18
  • 43
  • Can you post the whole code of the application or a minimal app with the error? I have the strong feeling that it's a very simple error (such as importing a different class named GlobalVariables) or something even more simple. – Augusto Jun 25 '11 at 22:36
  • done (names have changed a bit.. but in essence, everything should be the same.) – Rob Jun 25 '11 at 23:03
  • I'm really sorry Rob, I went through the code 4 times and I can't spot the problem :( – Augusto Jun 25 '11 at 23:14
  • Me either, really frustrating for a new person like me. I just dont understand why it cant see it :( – Rob Jun 25 '11 at 23:19

5 Answers5

2

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();
    }
}
Squonk
  • 48,735
  • 19
  • 103
  • 135
  • I tried this but i am getting - GlobalVariables cannot be resolved to a type (I put GlobalVariables.getHoles(); in my main class, is that why?) I want to get the value from GlobalValues.java to MainApplication.java – Rob Jun 25 '11 at 21:24
  • My main class extends Activity, is that going to be a problem? Also when I created a new class (right click on my package > new > class) and make the MyAppHelper, and try to change it to protected, it throws an error saying Illegal modifier for the class EasyParHelper; only public, abstract & final are permitted – Rob Jun 25 '11 at 21:42
  • @Rob: My bad - the helper class should be public not protected, I'll edit. No, it doesn't matter that your main class extends Activity. Just make sure both your extended Application and your Activity are in the same package and you won't even need to import the Application class. I use 'helpers' regularly and this is how I do it. – Squonk Jun 25 '11 at 21:46
  • No Luck... To make sure we are on the same page.. one file is src > com.my.application > MainApplication.java and the other is src > com.my.application > MyAppHelper.java, then in MyAppHelper I have your top box of code, and in MainApplication.java I have public class MainApplication extends Activity implements OnClickListener { public static MyAppHelper helper = new MyAppHelper(); (and then the rest of the contents) if this is the case, I still get the following error: MyAppHelper cannot be resolved to a type – Rob Jun 25 '11 at 22:02
  • I also added the following to the manifest – Rob Jun 25 '11 at 22:03
  • Would it be easier to go to the Android chat room to discuss this more? – Rob Jun 25 '11 at 22:05
  • @Rob: I've edited my code examples slightly. Basically you have three components here...MyApplication, MyActivity and MyAppHelper. The 'helper' is the 'glue' between everything. If they're all in the same 'com.my.application' package then everything should resolve. If this still doesn't explain things then I may be able to go to chat but it won't be for an hour or so. – Squonk Jun 25 '11 at 22:20
  • @Rob: BTW, don't add non-android classes to the manifest - it's likely to confuse things badly. – Squonk Jun 25 '11 at 22:22
  • Alright, I've tried that... I have got to be doing something wrong. I dont understand even how I can call public static MyAppHelper helper = new MyAppHelper(); from one class and it works no problem but not from another... – Rob Jun 25 '11 at 22:46
0

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
Community
  • 1
  • 1
snatr
  • 1
  • 2
0

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

Jarek Potiuk
  • 19,317
  • 2
  • 60
  • 61
  • I have already added GlobalVariables to the manifest so that should be good. To import it should I just be able to: "import GlobalVariables;" – Rob Jun 25 '11 at 20:53
  • Is it in the same package? I recommend to close and open the project in Eclipse (or refresh). Sometimes some compilation errors might come from bad eclipse refreshes. – Jarek Potiuk Jun 25 '11 at 20:59
  • When I try to add it to the import list, even if I add import com.my.application.GlobalVariables; it says The import com.my.applicaiton.GlobalVariables cannot be resolved. Is this because its extending application instead of activity by chance? – Rob Jun 25 '11 at 21:02
  • Nope. You must have compilation error in GlobalVariables. And BTW - name it differently - end it with Application (MyApplication, GlobalVariablesApplication) or smth.... This is the used convention – Jarek Potiuk Jun 25 '11 at 21:07
  • no error in GlobalVariables.java, seems to be compiling just fine :( In MainApplication.java though is where i am getting the errors. It just seems to not be able to see GlobalVariables.java for some reason – Rob Jun 25 '11 at 21:26
0

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.

Alex Gitelman
  • 24,429
  • 7
  • 52
  • 49
  • I do have package com.my.application; at the beginning, the GlobalVariables.java file has no errors at all. Unfortunately, I tried what you mentioned above and still no dice :( I just get Multiple markers at this line - GlobalVariables cannot be resolved to a type - GlobalVariables cannot be resolved to a type everywhere – Rob Jun 25 '11 at 21:22
0

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.

rf43
  • 4,385
  • 3
  • 23
  • 28
  • I understand what you are saying about major confusion if something goes wrong. What I am trying to avoid however, is having to edit each variable multiple times if I change 1 thing. Instead I would rather change it in 1 place and have it change the entire application where it is being used. For values that may cause issues, I will likely not use global variables. – Rob Jun 25 '11 at 21:25
  • 1
    Then I would definitley recommend using the string resource file for this. For example I use SharedPreferences and for the key in the key/value pair I use a string resource because it is globally available. Thus it would look like this.mSharPref.getInt(this.getString(R.string.somevalue), 0); – rf43 Jun 25 '11 at 21:56
  • @Rob btw while all the other answers are feasible, I think if you go the route of using the string prefs for this, you will find that it is **WAY** simpler and **WAY** easier to maintain. It also has the benefit of letting Android do its job and you do yours... e.g. Object creation/release. – rf43 Jun 25 '11 at 22:04