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

时间:2014-09-18 01:56:33

标签: java android xml colors android-logcat

我不知道为什么这会导致我的应用崩溃。我已经实例化了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,它导致我的应用程序停止工作或灰色,但当我将它传递给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

最后注意:现在设置代码的方式有效,颜色正确,应用程序在我的设备上运行,只有当我用未注释的代码切换注释代码时才会出错。这是我在这里的第一个问题,所以我希望以前没有问过,我正确格式化了,谢谢你的帮助!

3 个答案:

答案 0 :(得分:0)

想象一下: R.color.dark 就像一个指针指向颜色的值(当然不是像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 可能为空。

这是Activity的构造函数(ContextThemeWrapper的子类):

public Activity ()

Activity Constructor

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

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

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

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

这个答案可能有些错误,如果你想了解更多,请阅读来源:

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

答案 1 :(得分:0)

您在活动生命周期中过早地致电getResources()

该活动仅在Context或更高版本中用作onCreate()。实例初始化(堆栈跟踪中的<init>)太早了。将getResources()等移至onCreate()或更高版本。

答案 2 :(得分:0)

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

java.lang.NullPointerException:尝试调用虚方法&#39; android.content.res.Resources android.content.Context.getResources()&#39;在空对象引用上

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

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