Search code examples
javaandroidandroid-contextapplicationcontext

Why do I get NPE when I invoke android.content.Context.getApplicationContext() within Application's constructor?


My Application class looks something similar to this,

public class MyApplication extends Application {

    private static final String TAG = MyApplication.class.getSimpleName();
    public static Context mContext;

    public MyApplication() {
        Log.i(TAG, "Inside my application.. " + this);
        Log.i(TAG, "Value of application context is  : " + this.getApplicationContext());
        mContext = this;
    }
} 

I get NPE and my app is crashing when I do something like above,

12-15 12:03:57.886  8174  8174 D AndroidRuntime: Shutting down VM
12-15 12:03:57.890  8174  8174 E AndroidRuntime: FATAL EXCEPTION: main
12-15 12:03:57.890  8174  8174 E AndroidRuntime: Process: com.example.gm, PID: 8174
12-15 12:03:57.890  8174  8174 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate application com.example.gm.MyApplication: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.LoadedApk.makeApplication(LoadedApk.java:1087)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.ActivityThread.handleBindApplication(ActivityThread.java:5905)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.ActivityThread.access$1100(ActivityThread.java:207)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1660)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:106)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:193)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:6734)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
12-15 12:03:57.890  8174  8174 E AndroidRuntime: Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:116)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at com.example.gm.MyApplication.<init>(MyApplication.java:12)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at java.lang.Class.newInstance(Native Method)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.AppComponentFactory.instantiateApplication(AppComponentFactory.java:50)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at androidx.core.app.CoreComponentFactory.instantiateApplication(CoreComponentFactory.java:49)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.Instrumentation.newApplication(Instrumentation.java:1120)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    at android.app.LoadedApk.makeApplication(LoadedApk.java:1079)
12-15 12:03:57.890  8174  8174 E AndroidRuntime:    ... 9 more

Whereas in plain java code for a class which looks something like this,

public class Student {
    int age;
    String name;
    String badgeid;

    public Student(int age, String name) {
        this.age = age;
        this.name = name;
        this.badgeid = this.age + this.name;
    }
}

does not cause NPE when I do this.age and this.name. How do the above application snippet is something different than the below?


Solution

  • How do the above application snippet is something different than the below?

    Student has no superclass (other than Object, the default). You are referencing fields that you defined yourself on Student.

    Application has superclasses, as you can see in the documentation. So, let's add a superclass to your Student:

    public class Base {
      String something;
    
      public void onCreate() {
        something = "a value";
      }
    }
    
    public class Student extends Base {
        int age;
        String name;
        String badgeid;
        int value;
    
        public Student(int age, String name) {
            this.age = age;
            this.name = name;
            this.badgeid = this.age + this.name;
            this.value = something.length;
        }
    }
    

    Here, you will crash with a NullPointerException, because something is null at the time that you try calling something.length. The superclass does not set something to a value until onCreate() is called. You are referencing something too early.

    Similarly, you cannot call methods exposed by Context until the appropriate time. In the case of Application, Activity, and Service, that is after your onCreate() calls super.onCreate().