javaandroidnullpointerexceptiononcreatemain-activity

Why can't i call a method within a protected method of the same class


Within the MainActivity class I have got two methods - one public another protected.I am calling the public method from the protected method.I am running the app and the app crashes.If i cut/paste the code in the protected method everything works fine.One possibility-its not getting called properly.Why is it crashing?

Code---

public void generateQuestion() {

   Random rand = new Random();
   int a = rand.nextInt(21);
   int b = rand.nextInt(21);

   question.setText(Integer.toString(a) + "+" + Integer.toString(b));
   int locationOfCorrectAnswer = rand.nextInt(4);

   int incorrectAnswer;

   for (int i = 0; i < 4; i++) {

       if (i == locationOfCorrectAnswer) {
           answers.add(a + b);
       } else {
           incorrectAnswer = rand.nextInt(41);
           while (incorrectAnswer == a + b) {

               incorrectAnswer = rand.nextInt(41);

           }
           answers.add(incorrectAnswer);
       }
   }
   button1.setText(Integer.toString(answers.get(0)));
   button2.setText(Integer.toString(answers.get(1)));
   button3.setText(Integer.toString(answers.get(2)));
   button4.setText(Integer.toString(answers.get(3)));


}




@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    goButton = (Button) findViewById(R.id.goButton);
    question = (TextView) findViewById(R.id.question);
    pagetimer = (TextView) findViewById(R.id.pagetimer);
    noIndiacator = (TextView) findViewById(R.id.noIndiacator);
    resulttext = (TextView) findViewById(R.id.noIndiacator);
    Button button1 = (Button) findViewById(R.id.button1);
    Button button2 = (Button) findViewById(R.id.button2);
    Button button3 = (Button) findViewById(R.id.button3);
    Button button4 = (Button) findViewById(R.id.button4);

    generateQuestion();

}

LogCat---

10-25 17:17:57.688 13344-13344/? I/zygote: Not late-enabling -Xcheck:jni (already on)
10-25 17:17:57.699 13344-13344/? W/zygote: Unexpected CPU variant for X86 using defaults: x86
10-25 17:17:58.277 13344-13344/com.example.saurabhdutta.brainteser I/InstantRun: starting instant run server: is main process
10-25 17:17:58.650 13344-13355/com.example.saurabhdutta.brainteser I/zygote: Background concurrent copying GC freed 3526(1172KB) AllocSpace objects, 0(0B) LOS objects, 68% free, 693KB/2MB, paused 1.023ms total 141.970ms
10-25 17:17:58.739 13344-13344/com.example.saurabhdutta.brainteser D/AndroidRuntime: Shutting down VM


                                                                                     --------- beginning of crash
10-25 17:17:58.741 13344-13344/com.example.saurabhdutta.brainteser E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                     Process: com.example.saurabhdutta.brainteser, PID: 13344
                                                                                     java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.saurabhdutta.brainteser/com.example.saurabhdutta.brainteser.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setText(java.lang.CharSequence)' on a null object reference
                                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
                                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                                                                                         at android.app.ActivityThread.-wrap11(Unknown Source:0)
                                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                                                                                         at android.os.Handler.dispatchMessage(Handler.java:105)
                                                                                         at android.os.Looper.loop(Looper.java:164)
                                                                                         at android.app.ActivityThread.main(ActivityThread.java:6541)
                                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                                         at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                                                                                      Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setText(java.lang.CharSequence)' on a null object reference
                                                                                         at com.example.saurabhdutta.brainteser.MainActivity.generateQuestion(MainActivity.java:50)
                                                                                         at com.example.saurabhdutta.brainteser.MainActivity.onCreate(MainActivity.java:95)
                                                                                         at android.app.Activity.performCreate(Activity.java:6975)
                                                                                         at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                                                                                         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                                                                                         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
                                                                                         at android.app.ActivityThread.-wrap11(Unknown Source:0) 
                                                                                         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                                                                                         at android.os.Handler.dispatchMessage(Handler.java:105) 
                                                                                         at android.os.Looper.loop(Looper.java:164) 
                                                                                         at android.app.ActivityThread.main(ActivityThread.java:6541) 
                                                                                         at java.lang.reflect.Method.invoke(Native Method) 
                                                                                         at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

Solution

  • You are creating local variables of button1, button2 etc inside the onCreate method. This way, the generateQuestion method is unaware of these variables and uses the class variables with the same name (not included in your code, but I imagine you have somewhere declared them probably on top of your activity class) which are not initialized hence you get the NullPointerException.

    Try changing your generateQuestion to:

    public void generateQuestion(Button button1, Button button2, Button button3, Button button4) {
    
       Random rand = new Random();
       int a = rand.nextInt(21);
       int b = rand.nextInt(21);
    
       question.setText(Integer.toString(a) + "+" + Integer.toString(b));
       int locationOfCorrectAnswer = rand.nextInt(4);
    
       int incorrectAnswer;
    
       for (int i = 0; i < 4; i++) {
    
           if (i == locationOfCorrectAnswer) {
               answers.add(a + b);
           } else {
               incorrectAnswer = rand.nextInt(41);
               while (incorrectAnswer == a + b) {
    
                   incorrectAnswer = rand.nextInt(41);
    
               }
               answers.add(incorrectAnswer);
           }
       }
       button1.setText(Integer.toString(answers.get(0)));
       button2.setText(Integer.toString(answers.get(1)));
       button3.setText(Integer.toString(answers.get(2)));
       button4.setText(Integer.toString(answers.get(3)));
    
    
    }
    

    and call it from onCreate like this:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        goButton = (Button) findViewById(R.id.goButton);
        question = (TextView) findViewById(R.id.question);
        pagetimer = (TextView) findViewById(R.id.pagetimer);
        noIndiacator = (TextView) findViewById(R.id.noIndiacator);
        resulttext = (TextView) findViewById(R.id.noIndiacator);
        Button button1 = (Button) findViewById(R.id.button1);
        Button button2 = (Button) findViewById(R.id.button2);
        Button button3 = (Button) findViewById(R.id.button3);
        Button button4 = (Button) findViewById(R.id.button4);
    
        generateQuestion(button1, button2, button3, button4);
    
    }
    

    This way you will pass the local variables inside the generateQuestion method.