【问题标题】:Can I create custom global methods in my Android Application class?我可以在我的 Android 应用程序类中创建自定义全局方法吗?
【发布时间】:2010-08-17 15:04:53
【问题描述】:

我目前有一个包含许多活动的应用程序,并且需要有一种方法来维护这些活动之间的状态。

我使用 Application 类来执行此操作,声明我的全局变量并使用 getter 和 setter 与我的活动进行交互。

我希望在其中放置一些自定义方法,这样当我想做一个常见的任务时,例如显示一条错误消息,我可以在我的应用程序类中声明该方法并从任何活动中调用它使用它

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

EscarApplication 是我上面的应用程序类的名称。

我试图在我的应用程序类中包含这个方法:

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();
    }

希望我可以从活动中调用此方法而不必重新声明它,但是当我使用如下所示的方法调用它时,我得到一个空指针异常:

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

Visit 是上面我当前活动的名称。

这是否可行,或者我只能使用 getter 和 setter 来更改应用程序类中的全局变量。

堆栈跟踪:

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)

对话框在应用程序类中是这样声明的:

AlertDialog alertDialog;

在同一个类中创建:

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

在该类中调用它的方法如下:

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();
    }

最后,它是从这样的活动中调用的:

EscarApplication application;
application = (EscarApplication) this.getApplication();
application.showError("test", "display this message");

【问题讨论】:

  • 这是重复的,这里已经详细解答了:stackoverflow.com/questions/708012/…
  • 这不是一个重复的问题。我一直在使用应用程序类来访问全局变量。我问的问题是我可以有全局方法吗,特别是我可以有一个可以从任何活动触发的全局 AlertDialog
  • 我不确定你的意思。我在最初的问题中已经说过,我有一个用于记录状态的应用程序类。那就是你链接所指的。我想知道我是否可以超越仅仅设置和获取全局变量,以及我是否可以拥有可以从任何活动中调用的全局方法,例如我想要设置的自定义 AlertDialog。如果你的意思是我是否尝试过这个,然后是的,我有,正如我原来的问题中所述,当我尝试调用我的警报对话框时,我得到一个空点异常错误。
  • 您可以为您的 NPE 发布堆栈跟踪吗?我感觉你的 alertDialog 在调用 showError 之前没有被初始化。
  • 嗨,Erich,我在问题中包含了一个堆栈跟踪,以及我如何尝试调用它的详细信息。 - 谢谢

标签: global-variables android


【解决方案1】:

如果您需要在活动之间维护状态,请使用服务。其他的都是hack

【讨论】:

    【解决方案2】:

    如果我错了,有人纠正我,但是应用程序类将无法执行与视图相关的对象,因为它们需要绑定到需要绑定到活动的视图。

    从这个意义上说,您可以使用 Application 类来实现自定义对话框的静态方法

    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;
                }
            });
    }
    

    但是您必须创建对话框并在活动本身上调用show 方法(实际上,甚至可能需要在活动中创建要在对话框中设置的按钮

    另一种选择是实现一个类,extends AlertDialog 类,其按钮已预设为您想要的行为。

    【讨论】:

      【解决方案3】:

      你可以使用单例模式。

      【讨论】:

      • 老实说,这是一个糟糕的答案。我不知道你在说什么,你根本没有暗示你的意思。我不能降级,因为我的声望低于 100,但这有点懒惰。
      • OP 是对的。如果您要提出答案,请更加详细。
      • 什么东西这么难理解?你不能在这里搜索 Singleton 吗?大约有 500 个示例。我讨厌人们仅仅因为他们不理解一个好的答案而对它投反对票。
      • @androidworkz 我的意思是,对于一个非常具体的问题,它是一个非常模糊的答案。这里有一些人会花时间阅读一个问题,如果他们有解决方案来提出建议,还有一些人会留下一句话答案并期望得到公认的答案。我更喜欢前者。似乎 3 个答案中没有一个人真正阅读过这个问题。
      • 答案是你不能从你的应用程序类中静态启动一个 alertdialog 有两个原因......首先......你的方法不是静态的,你的类也不是......其次, alertbox 需要一个有效的上下文......你没有提供。如果你想显示一个这样的警告对话框,你必须创建自己的 alertdialog 类...因为 android alertdialog 不会那样工作。
      【解决方案4】:

      我希望实现与您类似的目标。

      我还没有找到官方答案,但看起来您不应该将应用程序上下文用于 Toast 和 Dialogs。相反,请尝试使用 Activity 的上下文,如下所示:

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

      而不是这个:

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

      阅读: Android: ProgressDialog.show() crashes with getApplicationContext

      【讨论】:

        猜你喜欢
        • 2018-03-10
        • 2011-10-27
        • 1970-01-01
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-27
        相关资源
        最近更新 更多