0

In a class i am taking we have been learning some android app development and such, and i have managed to run into a problem that I, for the life of me, cannot figure out...

Basic background...

I get a nullpointerexception when I rotate the device... This error is located at Line 100 of QuizActivity.....

this Line is : mCheatButton.setOnClickListener(new View.OnClickListener() {//....

I suspect this has something to do with storing or retrieving information from the bundle...

Anyways here is the rest of The code....

Here is my quiz activity... Sorry for all the code blocks, I dont really know a better way to give you this information, or if you even need all of it.... But right now I just can figure out what is going on... so i have printed the error (stack trace? i think that is the right term...).. here as well...

    03-02 09:49:28.858 7921-7921/com.example.ryan.ryans_quiz E/AndroidRuntime: FATAL EXCEPTION: main
                                                                       Process: com.example.ryan.ryans_quiz, PID: 7921
                                                                       java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.ryan.ryans_quiz/com.example.ryan.ryans_quiz.QuizActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                           at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                           at android.os.Looper.loop(Looper.java:148)
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                           at java.lang.reflect.Method.invoke(Native Method)
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                        Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
                                                                           at com.example.ryan.ryans_quiz.QuizActivity.onCreate(QuizActivity.java:100)
                                                                           at android.app.Activity.performCreate(Activity.java:6237)
                                                                           at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                           at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                           at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                                           at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                           at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                                           at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                           at android.os.Looper.loop(Looper.java:148) 
                                                                           at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                           at java.lang.reflect.Method.invoke(Native Method) 
                                                                           at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                           at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 

QuizActivity

  package com.example.ryan.ryans_quiz;

  import android.app.Activity;
  import android.content.Intent;
  import android.os.Bundle;
  import android.support.v7.app.AppCompatActivity;
  import android.util.Log;
  import android.view.View;
  import android.widget.Button;
  import android.widget.ImageButton;
  import android.widget.TextView;
  import android.widget.Toast;

  public class QuizActivity extends AppCompatActivity {

private static final String TAG = "QuizActivity";
private static final String KEY_INDEX = "index";
private static final int REQUEST_CODE_CHEAT = 0;

private Button mTrueButton;
private Button mFalseButton;
private ImageButton mNextButton;
private Button mCheatButton;
private TextView mQuestionTextView;

private Question[] mQuestionBank = new Question[] {
        new Question(R.string.question_oceans, true),
        new Question(R.string.question_mideast, false),
        new Question(R.string.question_africa, false),
        new Question(R.string.question_americas, true),
        new Question(R.string.question_asia, true)
};

private int mCurrentIndex = 0;

private boolean mIsCheater;

private void updateQuestion() {
    int question = mQuestionBank[mCurrentIndex].getTextResId();
    mQuestionTextView.setText(question);
}

private void checkAnswer(boolean userPressedTrue) {
    boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();

    int messageResId = 0;

    if (mIsCheater) {
        messageResId = R.string.judgment_toast;
    } else {
        if (userPressedTrue == answerIsTrue) {
            messageResId = R.string.correct_toast;
        } else {
            messageResId = R.string.incorrect_toast;
        }
    }

    Toast.makeText(this, messageResId, Toast.LENGTH_SHORT)
            .show();
}

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        mCurrentIndex = savedInstanceState.getInt(KEY_INDEX, 0);
    }
    super.onCreate(savedInstanceState);
    Log.d(TAG, "onCreate(Bundle) called");
    setContentView(R.layout.activity_quiz);

    mQuestionTextView = (TextView) findViewById(R.id.question_text_view);

    mTrueButton = (Button) findViewById(R.id.trueButton);
    mTrueButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            checkAnswer(true);
        }
    });

    mFalseButton = (Button) findViewById(R.id.falseButton);
    mFalseButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            checkAnswer(false);
        }
    });

    mNextButton = (ImageButton) findViewById(R.id.nextButton);
    mNextButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            mCurrentIndex = (mCurrentIndex + 1) % mQuestionBank.length;
            mIsCheater = false;
            updateQuestion();
        }
    });

    mCheatButton = (Button)findViewById(R.id.cheatButton);
    mCheatButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            boolean answerIsTrue = mQuestionBank[mCurrentIndex].isAnswerTrue();
            Intent i = CheatActivity.newIntent(QuizActivity.this, answerIsTrue);
            startActivityForResult(i, REQUEST_CODE_CHEAT);
        }
    });



    updateQuestion();
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putInt(KEY_INDEX, mCurrentIndex);
}

@Override
protected void onStart() {
    super.onStart();
    Log.d(TAG, "onStart() called");
}

@Override
protected void onPause() {
    super.onPause();
    Log.d(TAG, "onPause() called");
}

@Override
protected void onResume() {
    super.onResume();
    Log.d(TAG, "onResume() called");
}

@Override
protected void onStop() {
    super.onStop();
    Log.d(TAG, "onStop() called");
}

@Override
protected void onDestroy() {
    super.onDestroy();
    Log.d(TAG, "onDestroy() called");
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode != Activity.RESULT_OK) {
        return;
    }

    if (requestCode == REQUEST_CODE_CHEAT) {
        if (data == null) {
            return;
        }
        mIsCheater = CheatActivity.wasAnswerShown(data);
    }
}
   }

My CheatActivity class

  package com.example.ryan.ryans_quiz;

  import android.animation.Animator;
  import android.animation.AnimatorListenerAdapter;
  import android.content.Context;
  import android.content.Intent;
  import android.os.Build;
  import android.os.Bundle;
  import android.support.design.widget.FloatingActionButton;
  import android.support.design.widget.Snackbar;
  import android.support.v7.app.AppCompatActivity;
  import android.support.v7.widget.Toolbar;
  import android.view.Menu;
  import android.view.MenuItem;
  import android.view.View;
  import android.view.ViewAnimationUtils;
  import android.widget.Button;
  import android.widget.TextView;

  public class
    CheatActivity extends AppCompatActivity {
       private static final String EXTRA_ANSWER_IS_TRUE =
        "com.bignerdranch.android.geoquiz.answer_is_true";
       private static final String EXTRA_ANSWER_SHOWN =
        "com.bignerdranch.android.geoquiz.answer_shown";

   private boolean mAnswerIsTrue;

   private TextView mAnswerTextView;
   private Button mShowAnswer;

   public static Intent newIntent(Context packageContext, boolean answerIsTrue) {
    Intent i = new Intent(packageContext, CheatActivity.class);
    i.putExtra(EXTRA_ANSWER_IS_TRUE, answerIsTrue);
    return i;
}

   public static boolean wasAnswerShown(Intent result) {
    return result.getBooleanExtra(EXTRA_ANSWER_SHOWN, false);
}

   private void setAnswerShownResult(boolean isAnswerShown) {
    Intent data = new Intent();
    data.putExtra(EXTRA_ANSWER_SHOWN, isAnswerShown);
    setResult(RESULT_OK, data);
}

   @Override
   protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_cheat);

    mAnswerIsTrue = getIntent().getBooleanExtra(EXTRA_ANSWER_IS_TRUE, false);

    mAnswerTextView = (TextView)findViewById(R.id.answer_text_view);
    mShowAnswer = (Button)findViewById(R.id.show_answer_button);
    mShowAnswer.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mAnswerIsTrue) {
                mAnswerTextView.setText(R.string.trueButton);
            } else {
                mAnswerTextView.setText(R.string.falseButton);
            }
            setAnswerShownResult(true);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                int cx = mShowAnswer.getWidth() / 2;
                int cy = mShowAnswer.getHeight() / 2;
                float radius = mShowAnswer.getWidth();
                Animator anim = ViewAnimationUtils
                        .createCircularReveal(mShowAnswer, cx, cy, radius, 0);
                anim.addListener(new AnimatorListenerAdapter() {
                    @Override
                    public void onAnimationEnd(Animator animation) {
                        super.onAnimationEnd(animation);
                        mAnswerTextView.setVisibility(View.VISIBLE);
                        mShowAnswer.setVisibility(View.INVISIBLE);
                    }
                });
                anim.start();
            } else {
                mAnswerTextView.setVisibility(View.VISIBLE);
                mShowAnswer.setVisibility(View.INVISIBLE);
            }
        }
    });

}

my Question Class

    package com.example.ryan.ryans_quiz;

    /**
             * Created by Ryan on 1/20/2016.
     */
    public class Question {
        private int mTextResId;
        private boolean mAnswerTrue;

        public Question(int _textResId, boolean _answerTrue) {
            mTextResId = _textResId;
            mAnswerTrue = _answerTrue;
                }

        public int getTextResId() {
            return mTextResId;
        }

        public void setTextResId(int textResId) {
            mTextResId = textResId;
        }

        public boolean isAnswerTrue() {
    return mAnswerTrue;
}

public void setAnswerTrue(boolean answerTrue) {
    mAnswerTrue = answerTrue;
}

    }

And finally my xml Files....

activity_cheat

  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_gravity="center"
          android:orientation="vertical"
          tools:context="com.example.ryan.ryans_quiz.CheatActivity">

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:padding="24dp"
    android:text="@string/warning_text"/>

<TextView
    android:id="@+id/answer_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:padding="24dp"
    tools:text="Answer"/>

<Button
    android:id="@+id/show_answer_button"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:text="@string/show_answer_button"/>


  </LinearLayout>

LandLayout - activity_quiz

  <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:gravity="center"
         android:orientation="vertical">

<TextView
    android:id="@+id/question_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal"
    android:padding="24dp"/>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center_horizontal|center_vertical"
    android:orientation="vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical"
        android:orientation="horizontal">

        <Button
            android:id="@+id/trueButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/trueButton"/>

        <Button
            android:id="@+id/falseButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/falseButton"/>
    </LinearLayout>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        android:text="@string/cheat_button"/>

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal|center_vertical"
        android:orientation="horizontal">

        <ImageButton
            android:id="@+id/previousButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:contentDescription="@string/previousButton"
            android:src="@drawable/arrow_left"/>

        <ImageButton
            android:id="@+id/nextButton"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center_horizontal|center_vertical"
            android:contentDescription="@string/nextButton"
            android:src="@drawable/arrow_right"/>

    </LinearLayout>
  </LinearLayout>
 </FrameLayout>

vertical layout- activity_quiz

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:orientation="vertical">

<TextView
    android:id="@+id/question_text_view"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="24dp"/>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <Button
        android:id="@+id/trueButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/trueButton"/>

    <Button
        android:id="@+id/falseButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/falseButton"/>

</LinearLayout>

<Button
    android:id="@+id/cheatButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/cheat_button"/>

<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

    <ImageButton
        android:id="@+id/previousButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/previousButton"
        android:src="@drawable/arrow_left"/>

    <ImageButton
        android:id="@+id/nextButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:contentDescription="@string/nextButton"
        android:src="@drawable/arrow_right"/>


  </LinearLayout>
 </LinearLayout>

Strings..

  <resources>
<string name="app_name">RyanHull_Quiz</string>
<string name="action_settings">Settings</string>

<string name="trueButton">True</string>
<string name="falseButton">False</string>
<string name="nextButton">Next</string>
<string name="previousButton">Previous</string>
<string name="cheat_button">Cheat!</string>

<string name="correct_toast">Correct! :)</string>
<string name="incorrect_toast">Incorrect! :(</string>"

<string name="question_oceans">The Pacific Ocean is larger than the Atlantic Ocean.</string>
<string name="question_mideast">The Suez Canal connects the Red Sea and the Indian Ocean.</string>
<string name="question_africa">The source of the Nile River is in Egypt.</string>
<string name="question_americas">The Amazon River is the longest river in the Americas.</string>
<string name="question_asia">Lake Baikal is the world\'s oldest and deepest freshwater lake.</string>

<string name="warning_text">Are you sure you want to do this??</string>
<string name="show_answer_button">Show Answer</string>
<string name="judgment_toast">Cheating is Wrong 8/</string>
<string name="title_activity_cheat">Cheat</string>

and finally manifest....

      <?xml version="1.0" encoding="utf-8"?>
      <manifest package="com.example.ryan.ryans_quiz"
      xmlns:android="http://schemas.android.com/apk/res/android">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
    <activity android:name=".QuizActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>

            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
    <!--
         ATTENTION: This was auto-generated to add Google Play services to your project for
         App Indexing.  See https://g.co/AppIndexing/AndroidStudio for more information.
    -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version"/>

    <activity
        android:name=".CheatActivity"
        android:label="@string/title_activity_cheat"
        android:theme="@style/AppTheme.NoActionBar">
    </activity>
</application>

EDIT: its not a matter of me know what the exception is.. More of the matter of find where and why...

R.Hull
  • 126
  • 1
  • 8
  • I know that I am referencing an object that hasint been instantiated, I can't figure out why it's not been instansiated – R.Hull Mar 02 '16 at 14:57
  • @R.Hull Because you haven't assigned any id to the cheat button in landscape layout. see my answer. – Rohit5k2 Mar 02 '16 at 15:03
  • This is way too much code to expect anyone to read. – khelwood Mar 02 '16 at 15:05
  • I know, that's why i pointed out the location of the error, so it could be decided what was needed to read, and what was not, the problem was I did not know where that might be – R.Hull Mar 02 '16 at 15:07

3 Answers3

1

The lookup is failing for mCheatButton because you forgot to assign it an id in the landscape version of the activity_quiz.xml layout file.

When you then try to set a ClickListener on a null object that is where the NullPointerException is coming from.

George Mulligan
  • 11,813
  • 6
  • 37
  • 50
1

when you rotate the device,the QuizActivity will destroy and then call onCreate,but your LandLayout file has no Button called 'cheatButton',so findViewById(R.id.cheatButton) will return null to mCheatButton, it can not call any method.

linjiang
  • 116
  • 10
0

You haven't assigned any id to cheat button in LandLayout - activity_quiz

Change

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"
    android:text="@string/cheat_button"/>

to

<Button
    android:id="@+id/cheatButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="bottom|center"
    android:text="@string/cheat_button"/>
Rohit5k2
  • 17,948
  • 8
  • 45
  • 57