Android 在Java中声明全局常量-但避免NullPointerException错误

Android 在Java中声明全局常量-但避免NullPointerException错误,android,macros,constants,Android,Macros,Constants,我在几篇关于如何申报全球合同的帖子中遵循了这里给出的建议: public class Constants { public static final int i1 = 1; public static final int i2 = 2; } 我只是将此类包括在我的项目中,并引用如下常量: in any other class... GlobalsVars.gi1 = Constants.i1; (顺便说一句,我希望这是可以的,不需要对Constants类做

我在几篇关于如何申报全球合同的帖子中遵循了这里给出的建议:

public class Constants {

    public static final int i1 = 1;
    public static final int i2 = 2; 
    }
我只是将此类包括在我的项目中,并引用如下常量:

in any other class...
    GlobalsVars.gi1 = Constants.i1;
(顺便说一句,我希望这是可以的,不需要对Constants类做任何事情,比如初始化或其他任何事情。)

但正如我在这里发现的:使用静态全局变量不是一个好主意。我的应用程序在访问常量时有时会崩溃

虽然我觉得这很奇怪,因为我的应用程序相当小,但在某些情况下,可能是Constants类(不是活动)从内存中删除了,尽管我在所有活动中都访问它的常量。这就是为什么我认为无论如何都不应该从记忆中删除它

但可以肯定的是,在某些情况下,当访问Constants.i1值时,我的应用程序会崩溃

以可靠的方式声明某些常量的最佳方式是什么。(在c-衍生品中有易于使用的宏),但Android中没有类似的宏

->我只需要Java中的“可靠”常量…

编辑:

添加了GlobalVars类的声明

public class GlobalVars {
    public static Integer gi1;
    public static Integer gi2;
}
非常感谢

编辑: 添加了崩溃日志

java.lang.RuntimeException:无法启动活动组件信息{com.xxxx.xxxx/com.xxxx.xxxx.screens.One_screen}:java.lang.NullPointerException 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1830)上 位于android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1851) 在android.app.ActivityThread.access,售价1500美元(ActivityThread.java:132) 在android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038) 位于android.os.Handler.dispatchMessage(Handler.java:99) 位于android.os.Looper.loop(Looper.java:150) 位于android.app.ActivityThread.main(ActivityThread.java:4293) 位于java.lang.reflect.Method.Invokenactive(本机方法) 位于java.lang.reflect.Method.invoke(Method.java:507) 在com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:849)上 位于com.android.internal.os.ZygoteInit.main(ZygoteInit.java:607) 在dalvik.system.NativeStart.main(本机方法) 原因:java.lang.NullPointerException 在com.xxxx.xxxx.screens.Settings\u screen.presentOnScreen上(One\u screen.java:172) 位于com.xxxx.xxxx.screens.Settings\u screen.onCreate(One\u screen.java:49) 位于android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1072) 在android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1794)上 ... 还有11个

一个屏幕中的第172行是:

if (GlobalVars.gi1 == Constants.i1){

在Java中,不需要使用static来使它们保持不变。您可以将它们设置为
final
public
,并以相对相同的方式访问它们。不过,不同之处在于,您必须创建一个带有引用的类实例,只要您想访问那些无实际原因而占用内存的常量。您可以通过以下模式来解决此问题,该模式将创建一个类实例,您可以通过static
getInstance()
方法访问该类。

您不需要在Java中使用static来使它们保持不变。您可以将它们设置为
final
public
,并以相对相同的方式访问它们。不过,不同之处在于,您必须创建一个带有引用的类实例,只要您想访问那些无实际原因而占用内存的常量。您可以通过以下模式来解决此问题,该模式将创建一个类实例,您可以通过静态
getInstance()
方法访问该类。

您遇到的更普遍的问题是如何跨多个活动和应用程序的所有部分保存状态。静态变量(例如,单例变量)是实现这一点的常用Java方法。然而,我发现在Android中,一种更优雅的方式是将您的状态与应用程序上下文关联起来

正如您所知,每个活动也是一个上下文,从最广泛的意义上讲,它是关于其执行环境的信息。您的应用程序也有一个上下文,Android保证它将作为单个实例存在于您的应用程序中

方法是创建自己的子类,然后在清单中的应用程序标记中指定该类。现在,Android将自动创建该类的实例,并使其可用于您的整个应用程序。您可以使用context.getApplicationContext()方法从任何上下文访问它(Activity还提供了一个方法getApplication(),该方法具有完全相同的效果):


这与使用静态变量或单例的效果基本相同,但与现有的Android框架集成得相当好。请注意,这不会跨流程运行(如果您的应用程序是具有多个流程的少数应用程序之一)。

您遇到的更普遍的问题是如何跨多个活动和应用程序的所有部分保存状态。静态变量(例如,单例变量)是实现这一点的常用Java方法。然而,我发现在Android中,一种更优雅的方式是将您的状态与应用程序上下文关联起来

正如您所知,每个活动也是一个上下文,从最广泛的意义上讲,它是关于其执行环境的信息。您的应用程序也有一个上下文,Android保证它将作为单个实例存在于您的应用程序中

方法是创建自己的子类,然后在清单中的应用程序标记中指定该类。现在,Android将自动创建该类的实例,并使其可用于您的整个应用程序。您可以使用context.getApplicationContext()方法从任何上下文访问它(Activity还提供了一个方法getApplication(),该方法具有完全相同的效果):

这本质上与使用静态变量或单例具有相同的效果,但与我们完全相同
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();
    ...
  }
}
I got a crash report of my app in a place where it compares if (GlobalVars.gi1 == Constants.i1)