繁体   English   中英

Android:使用getResources可能会导致我的应用崩溃

[英]Android: Using getResources might be causing my app to crash

我不知道为什么这会导致我的应用崩溃。 我已经实例化了3个类变量,以指向我在colors.xml文件中创建的颜色值。 我一直在尝试,这里注释掉的代码似乎正在导致错误“ appName停止工作”

protected int m_nDarkColor = R.color.dark;
//protected int m_nDarkColor = getResources().getColor(R.color.dark);
protected int m_nLightColor = R.color.light;
//protected int m_nLightColor = getResources().getColor(R.color.light);
protected int m_nTextColor = R.color.text;
//protected int m_nTextColor = getResources().getColor(R.color.text);

private boolean isDark = false; //To alternate between colors.

这是在顶部使用类变量的方法。 如果我在setBackgroundColor()方法中使用未注释的类变量,则无论我将颜色值更改为什么,颜色都是相同的灰色阴影(这就是为什么我也将其注释掉了),因此我尝试了setBackgroundColor(getResources()get .Color(R.color.dark)并解决了这个问题,但是这使我的类变量无用了,我并不是故意要挑剔,我只是感到困惑,为什么当我将类变量设置为指向我的颜色值时colors.xml,它使我的应用程序停止工作或smae灰色,但是当我将其传递给setBackgroundColor方法时,它就可以正常工作。

protected void addJoke(String strJoke) {

    android.widget.TextView display = new android.widget.TextView(this);

    display.setText(strJoke); //Sets the text on display.

    display.setTextSize(16); //Increases the font size of the text.

    display.setTextColor(getResources().getColor(R.color.text));
    //display.setTextColor(m_nTextColor);

    if(!isDark)
    {
        display.setBackgroundColor(getResources().getColor(R.color.dark));
        //display.setBackgroundColor(m_nDarkColor);
        isDark = true;
    }
    else if(isDark)
    {
        display.setBackgroundColor(getResources().getColor(R.color.light));
        //display.setBackgroundColor(m_nLightColor);
        isDark = false;
    }
    m_vwJokeLayout.addView(display); //Adds the view to the layout.
}

这就是LogCat的全部红色

09-17 20:47:25.852: E/AndroidRuntime(11212): FATAL EXCEPTION: main
09-17 20:47:25.852: E/AndroidRuntime(11212): java.lang.RuntimeException: Unable to   instantiate activity ComponentInfo{edu.calpoly.android.lab2/edu.calpoly.android.lab2.SimpleJokeList}: java.lang.NullPointerException
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2106)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread.access$600(ActivityThread.java:141)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.os.Handler.dispatchMessage(Handler.java:99)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.os.Looper.loop(Looper.java:137)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread.main(ActivityThread.java:5039)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at java.lang.reflect.Method.invokeNative(Native Method)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at java.lang.reflect.Method.invoke(Method.java:511)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at dalvik.system.NativeStart.main(Native Method)
09-17 20:47:25.852: E/AndroidRuntime(11212): Caused by: java.lang.NullPointerException
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.content.ContextWrapper.getResources(ContextWrapper.java:89)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.view.ContextThemeWrapper.getResources(ContextThemeWrapper.java:78)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at edu.calpoly.android.lab2.SimpleJokeList.<init>(SimpleJokeList.java:34)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at java.lang.Class.newInstanceImpl(Native Method)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at java.lang.Class.newInstance(Class.java:1319)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.Instrumentation.newActivity(Instrumentation.java:1054)
09-17 20:47:25.852: E/AndroidRuntime(11212):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2097)
09-17 20:47:25.852: E/AndroidRuntime(11212):    ... 11 more

最后说明:现在可以设置代码的方式,可以正确显示颜色,并且应用程序可以在我的设备上运行,该错误仅在我用未注释的代码切换注释的代码时引起。 这是我在这里的第一个问题,所以希望以前没有被问过,我已经正确设置了格式,感谢您的帮助!

像这样想象: R.color.dark就像是指向 color值的指针(肯定不是像C语言一样真正的指针)。 然后使用getResources()。getColor(R.color.dark)方法获取颜色的真实值。

做一个测试:

   Log.d("Color", "Value of \"R.color.gray\" is: " + R.color.gray);
   Log.d("Color", "Value of \"getResources().getColor(R.color.gray)\" is: " + getResources().getColor(R.color.gray));

这是logCat的输出:

09-18 11:07:17.458  32359-32359/com.ch.summerrunner D/Color﹕ Value of "R.color.gray" is: 2131099651
09-18 11:07:17.458  32359-32359/com.ch.summerrunner D/Color﹕ Value of "getResources().getColor(R.color.gray)" is: -2144128205

值-2144128205表示Android系统中的真实颜色。 希望这对您有帮助。

- - - - - -加 - - - - - - -

我明白你的意思。

为什么您的应用崩溃?

因为getResources()方法返回null

但是,为什么在调用它来设置类变量时返回null?

很长的故事。

getResource()是Context的接口,由ContextWrapper实现。 像这样 :

  @Override
  public Resources getResources()
  {
      return mBase.getResources();
  }

但是ContextThemeWrapper(ContextWrapper的子类)的构造方法是:

  public ContextThemeWrapper() {
        super(null);
    }

  public ContextThemeWrapper(Context base, int themeres) {
        super(base);
        mBase = base;
        mThemeResource = themeres;
    }

您可以看到ContextWrapper的mBase可能为null。

这是Activity的构造方法(ContextThemeWrapper的子类):

public Activity ()

活动构造器

我们没有将上下文传递给Activity,因此ContextWrapper何时初始化mBase

当系统创建/启动活动时,系统通过活动的attachBaseContext(Context base)方法将mBase实例传递给活动。

这就是为什么在调用getResources()来设置类变量时得到NULL的原因。

您调用该方法为时过早。 稍后在onCreate()中调用getResources()。

该答案可能存在一些错误,如果您想了解更多,请阅读原文:

frameworks/base/core/java/android/app/ActivityThread.java

您在活动生命周期中太早调用getResources()

该活动仅在onCreate()或更高版本中可用作Context 实例初始化(堆栈跟踪中的<init> )为时过早。 getResources()等移动到onCreate()或更高版本。

我向应用程序添加了图标,然后从应用程序中删除了图标,然后在attachBaseContext上注释了代码。 应用开始出现此错误:

java.lang.NullPointerException:尝试在空对象引用上调用虚拟方法“ android.content.res.Resources android.content.Context.getResources()”

完全删除attachBaseContext之后,一切都很好。

@Override
    protected void attachBaseContext(Context newBase)
    {
        //super.attachBaseContext(IconicsContextWrapper.wrap(newBase));
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM