cjayem13
cjayem13

Reputation: 913

Null Error thrown after null check?

Can someone please explain why scoreTextSwitcher is getting a null error even though I'm checking with if statement? The error is thrown only after starting activity - changing screen orientation - changing screen orientation again - then error occurs...

if(scoreTextSwitcher != null) {
       scoreTextSwitcher.setText(String.valueOf(a));
}

I tried looking for the answer on the links below but couldn't figure out how it relates to my code. If so, can someone please clarify? Many Thanks.


Here is the whole method (not sure if being in a thread mattered)

 private void setScoreTextSwitcher(final int a){
    Thread setScore = new Thread() {
        public void run() {
            if(scoreTextSwitcher == null) {
                scoreTextSwitcher = (TextSwitcher) findViewById(R.id.score_text_switcher);

            }
            GameActivity.this.runOnUiThread(new Runnable() {
                public void run() {
                    if(scoreTextSwitcher != null) {
                        scoreTextSwitcher.setText(String.valueOf(a));
                    }
                }
            });
        }
    };
    setScore.start();
}

Here are the error messages:

08-27 11:02:10.226    2780-2780/com.major.color D/AndroidRuntime﹕ Shutting down VM
08-27 11:02:10.226    2780-2780/com.major.color W/dalvikvm﹕ threadid=1: thread exiting with uncaught exception (group=0x409961f8)
08-27 11:02:10.247    2780-2780/com.major.color E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.NullPointerException
            at android.widget.TextSwitcher.setText(TextSwitcher.java:78)
            at com.major.color.GameActivity$6$1.run(GameActivity.java:600)
            at android.os.Handler.handleCallback(Handler.java:605)
            at android.os.Handler.dispatchMessage(Handler.java:92)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:4340)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:511)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)

Here is another section of my program that is also getting a null pointer error. I believe it's the same issue because it only occurs when starting and changing the screen orientation back and forth.. Hopefully this second example can help narrow things down a bit.

 private void startCountDownTimer(){
    isTimerOn = true;
    timerTextSwitcher = (TextSwitcher) findViewById(R.id.timer_text_switcher);
    timer = new CountDownTimer(timerCount, 1000) {
        public void onTick(long millisUntilFinished) {
            isTimerOn = true;
            timerCount = millisUntilFinished;

            if ( millisUntilFinished < 10001) {
                TextView TextSwTextView = (TextView) timerTextSwitcher.getChildAt(0);
                TextSwTextView.setTextColor(Color.RED);
                TextSwTextView.setText(String.valueOf(millisUntilFinished / 1000));
            }else
                if(timerTextSwitcher != null){
                    timerTextSwitcher.setText(String.valueOf(millisUntilFinished / 1000));}else {
                    timerTextSwitcher = (TextSwitcher) findViewById(R.id.timer_text_switcher);
                    timerTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {

                        public View makeView() {
                            // Create a new TextView and set properties
                            TextView textView = new TextView(getApplicationContext());
                            textView.setLayoutParams(new TextSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
                            textView.setTextSize(17);
                            textView.setTextColor(Color.BLUE);

                            return textView;
                        }
                    });
                    timerTextSwitcher.setText(String.valueOf(millisUntilFinished / 1000));
                }
        }
   public void onFinish() {
            timerTextSwitcher.post(new Runnable() {
                @Override
                public void run() {
                    createToast("GAME OVER!");
                }
            });
            isTimerOn = false;

            saveScore();
            DialogFragment endDialog = new EndGameFragment();
            Dialog = endDialog;
            endgameVisible = true;
            endDialog.show(getSupportFragmentManager(), "EndGameDialogFragment");
        }
    };
    timer.start();
}

Portion of onCreate method displaying how I setup the TextSwitcher for score and Time of activity.

 @Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
            WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_game)
//more code...

 timerTextSwitcher = (TextSwitcher) findViewById(R.id.timer_text_switcher);
    timerTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {

        public View makeView() {
            // Create a new TextView and set properties
            TextView textView = new TextView(getApplicationContext());
            textView.setLayoutParams(new TextSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setTextSize(17);
            textView.setTextColor(Color.BLUE);

            return textView;
        }
    });
    scoreTextSwitcher = (TextSwitcher) findViewById(R.id.score_text_switcher);
    scoreTextSwitcher.setFactory(new ViewSwitcher.ViewFactory() {

        public View makeView() {
            // Create a new TextView and set properties
            TextView textView = new TextView(getApplicationContext());
            textView.setLayoutParams(new TextSwitcher.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
            textView.setTextSize(17);
            textView.setTextColor(Color.BLUE);
            textView.setText("0");
            return textView;
        }
    });

    // Declare the animations and initialize them
    Animation in = AnimationUtils.loadAnimation(this, android.R.anim.slide_in_left);
    Animation out = AnimationUtils.loadAnimation(this, android.R.anim.slide_out_right);

    // set the animation type to textSwitcher
    timerTextSwitcher.setInAnimation(in);
    timerTextSwitcher.setInAnimation(out);
    scoreTextSwitcher.setInAnimation(in);
    scoreTextSwitcher.setInAnimation(out);
}

Upvotes: 0

Views: 170

Answers (2)

Mike M.
Mike M.

Reputation: 39191

The following lines are causing the undesired behavior:

private void startCountDownTimer(){
    ...
    timerTextSwitcher = (TextSwitcher) findViewById(R.id.timer_text_switcher);

and:

private void setScoreTextSwitcher(final int a){
    ...
    scoreTextSwitcher = (TextSwitcher) findViewById(R.id.score_text_switcher);

These calls to findViewById() are re-initializing the Switchers, causing them to lose the Factory and Animation setups you've got in onCreate(), and causing an internal NullPointerException in the setText() method. Since, it appears, the Switchers are declared in the Activity's scope, you just need to remove those lines.

Upvotes: 1

raj
raj

Reputation: 2088

try this

private void setScoreTextSwitcher(final int a){
scoreTextSwitcher = (TextSwitcher) findViewById(R.id.score_text_switcher);
Thread setScore = new Thread() {
    public void run() {
        if(scoreTextSwitcher.isEmpty()) {
            Log.e("","Empty");

        }
        GameActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                if(scoreTextSwitcher != null) {
                    scoreTextSwitcher.setText(String.valueOf(a));
                }
            }
        });
    }
};
setScore.start();

}

Upvotes: 1

Related Questions