Reputation: 913
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
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
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