4

I currently have an app that has many activities and needs to have a way of maintaining state between these activities.

I use the Application class to do this, declaring my global variables and using getters and setters to interact with my activities.

I was hoping to place a few custom methods in there, so that when I want to do a common task like, for instance, display an error message, I can declare the method in my application class and call it from any activity that uses it

EscarApplication application = (EscarApplication) this.getApplication();

EscarApplication being the name of my application class above.

I have tried to include this method in my application class:

public void showError(String title, String message) {
        Log.i("Application level",message);
        this.alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                return;
            }
        });
        alertDialog.show();
    }

In the hope that I can call this method from activity without having to redeclare it, but when I call it using something like below I get an null pointer exception:

Visit.this.application.showError("Update error", "An error has occurred while trying to communicate with the server");

Visit being the name of my current activity above.

Should this work, or can I only use getters and setters to change global vars in an Application Class.

Stack Trace:

java.lang.RuntimeException: Unable to start activity ComponentInfo{escar.beedge/escar.beedge.HomeScreen}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
at android.app.ActivityThread.access$2100(ActivityThread.java:116)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4203)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
at dalvik.system.NativeStart.main(Native Method)
ERROR/AndroidRuntime(375): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRoot.setView(ViewRoot.java:460)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.app.Dialog.show(Dialog.java:238)
at escar.beedge.EscarApplication.showError(EscarApplication.java:98)
at escar.beedge.HomeScreen.onCreate(HomeScreen.java:30)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)

The dialog is declared as such in the application class:

AlertDialog alertDialog;

Created in that same class:

alertDialog = new AlertDialog.Builder(this).create();

and the method to call it in that class is as follows:

public void showError(String title, String message) {
        alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                return;
            }
        });
        alertDialog.show();
    }

And finally, it is called from an activity like so:

EscarApplication application;
application = (EscarApplication) this.getApplication();
application.showError("test", "display this message");
Bill the Lizard
  • 398,270
  • 210
  • 566
  • 880
Kevin Bradshaw
  • 6,327
  • 13
  • 55
  • 78
  • Could you post a stack trace for your NPE? I have a feeling your alertDialog isn't being initialized before calling showError. – Erich Douglass Aug 17 '10 at 17:35
  • Hi Erich, I have included a stack trace in the question and also details of how I am trying to call it. - thanks – Kevin Bradshaw Aug 17 '10 at 19:07
  • This is a duplicate, it has been answered in detail here: http://stackoverflow.com/questions/708012/android-how-to-declare-global-variables – fredley Aug 17 '10 at 15:07
  • 1
    This is not an duplicate question. I have been using application class to access global variables all along. The question I asked was can I have global methods, specificly can I have a global AlertDialog that I can trigger from any activity – Kevin Bradshaw Aug 17 '10 at 15:58
  • Im not to sure what you mean. I have stated in my original questiuon that I have an application class that I use to record state. Thats what you link refers to. I want to know if I can go beyond merely setting and getting global variables, and if I can have global methods that can be called from any activity such as the custom AlertDialog I wanted to set up., If you mean have I tried to do this, then yes I have, as stated in my original question I get an null point exception error when I try to call my alert dialog. – Kevin Bradshaw Aug 17 '10 at 16:09

4 Answers4

1

If you need to maintain state between activities, then use a service. Anything else is a hack

Falmarri
  • 47,727
  • 41
  • 151
  • 191
0

Someone correct me if Im wrong, but an Application class wont be able to execute view related objects as they need to be bound to a view which needs to be bound to an activity.

In that sense, you could use your Application class to implement a static method that customises the dialog

public static void setDialog(String title, String message,AlertDialog alertDialog){
        alertDialog.setTitle(title);
        alertDialog.setMessage(message);
        alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog,int which) {
                return;
            }
        });
}

but you would have to create the dialog and call the show method on the activities themselves (actually maybe even the button to be set in the dialog would need to be created on the activity)

Another option could be to implement a class that extends the AlertDialog class and whose button is pre-set to the behavior you want.

Thomas
  • 2,751
  • 5
  • 31
  • 52
-1

You could use the Singleton pattern.

Quentamia
  • 3,244
  • 3
  • 33
  • 42
  • 3
    honesly dude, thats a terrible answer. I have no clue what you are on about and you provide no hint at all as to what you mean. I cant downgrade as I have a sub 100 reputation, but that was a bit of a lazy answer. – Kevin Bradshaw Aug 17 '10 at 16:04
  • OP is right. If you're going to suggest an answer, be more elaborate. – Andrey Aug 17 '10 at 17:42
  • what is so hard to understand? You can't search Singleton here? There are about 500 examples.. I hate that people downvote a good answer just because they don't understand it. – androidworkz Aug 17 '10 at 18:47
  • @androidworkz My point is that it is a terribly vague answser to a very specific question. There are some people on here who take time to read a question and if they have a solution to suggest it, there are others who leave one sentence answers and expect to get the accepted answer. I prefer the former. It seems that of the 3 answers not one has really read the question. – Kevin Bradshaw Aug 17 '10 at 19:54
  • 1
    The answer is that you can't start an alertdialog from your application class statically for 2 reasons... first... your method isn't static and neither is your class... secondly, alertbox requires a valid context... which you didn't provide. If you want to show an alert dialog like that you will have to create your own alertdialog class... because the android alertdialog won't work like that. – androidworkz Aug 17 '10 at 20:27
  • Thanks Androidworkz.. I would use this as my accepted answer but youve added it as a comment. – Kevin Bradshaw Aug 18 '10 at 07:11
-1

I'm looking to achieve something similar to you.

I haven't found an official answer, but it looks like you shouldn't be using the application context for Toast and Dialogs. Instead, try using the context of an Activity like so :

// From inside your activity
Dialog dialog = new Dialog(this);

instead of this:

// From inside your Application instance
Dialog dialog = new Dialog(getApplicationContext());

Read this : Android: ProgressDialog.show() crashes with getApplicationContext

Community
  • 1
  • 1
David
  • 1,842
  • 2
  • 21
  • 31