简体   繁体   中英

Android: Using getResources might be causing my app to crash

I don't know why this is causing my app to crash. I have instantiated 3 class variables to point to the color values I created in my colors.xml file. I have been experimenting, and the code that is commented out here seems to be causing the error "appName has stopped working"

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.

This is the method that is using the class variables on top. If I use the uncommented class variables in the setBackgroundColor() methods, the color is the same gray shade no matter what I change the color values to (that is why I commented those out too), so I tried setBackgroundColor(getResources()get.Color(R.color.dark) and it fixed the problem, but it made my class variables useless. I don't mean to be picky, I am just confused why when I set the class variable to point to my colors values in colors.xml, it causes my app to stop working or the smae gray color, but when I pass it to the setBackgroundColor method it works just fine. `

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.
}

This is all the red from 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

Final Note: The way the code is set up now works, the colors come out right and the app runs on my device, the error is only caused when I switch the commented code with the uncommented code. This is my first question on here, so I hope it hasn't been asked before and I formatted it correctly, thanks for help!

Imagine like this: R.color.dark is like a pointer point to the value of color(Certainly not a real pointer like C language). And you use getResources().getColor(R.color.dark) method to get the real value of color.

Do a test:

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

Here is the output in 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

the value -2144128205 means the real color in Android system. May this help you.

-----------add--------------

I understand what you mean.

Why your app crashes?

Because getResources() method return null .

But why it return null when you call it to set the class variable?

Long Story.

getResource() is a interface of Context and implement by ContextWrapper. Like this :

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

But the Constructor of ContextThemeWrapper(Subclasses of ContextWrapper) is :

  public ContextThemeWrapper() {
        super(null);
    }

and

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

You can see that the mBase of ContextWrapper may be null.

This is the Constructor of Activity(Subclasses of ContextThemeWrapper):

public Activity ()

Activity Constructor

We did not pass a context to Activity, so when did ContextWrapper initialize mBase ?

When system create/start an Activity, system pass a mBase instance to Activity by attachBaseContext(Context base) method of Activity.

This is why you get NULL when you call getResources() to set the class variable.

You call the method too early. Call getResources() in onCreate() of later.

There may be some mistakes in this answer, if you wanna know more, read the source:

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

You are calling getResources() too early in the activity lifecycle.

The activity is usable as a Context only in onCreate() or later. Instance initialization ( <init> in your stacktrace) is too early. Move the getResources() and such to onCreate() or later.

I added iconics to app then after remove that from application I comment the code on attachBaseContext. App started to give this error:

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

After I remove attachBaseContext completely, everything is fine.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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