有人可以解释为什么scoreTextSwitcher得到一个空错误,即使我正在检查if语句?只有在启动活动后才会抛出错误 - 更改屏幕方向 - 再次更改屏幕方向 - 然后发生错误...
if(scoreTextSwitcher != null) {
scoreTextSwitcher.setText(String.valueOf(a));
}
我尝试在下面的链接上寻找答案,但无法弄清楚它与我的代码有什么关系。如果是这样,有人可以澄清一下吗?非常感谢。
这是整个方法(不确定是否在线程中重要)
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();
}
以下是错误消息:
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)
这是我的程序的另一部分,也是一个空指针错误。我相信它是同样的问题,因为它只发生在来回启动和改变屏幕方向时。希望这第二个例子可以帮助缩小范围。
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();
}
onCreate方法的一部分,显示我如何为得分和活动时间设置TextSwitcher。
@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);
}
答案 0 :(得分:1)
试试这个
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();
}
答案 1 :(得分:1)
以下行导致了不良行为:
private void startCountDownTimer(){
...
timerTextSwitcher = (TextSwitcher) findViewById(R.id.timer_text_switcher);
和
private void setScoreTextSwitcher(final int a){
...
scoreTextSwitcher = (TextSwitcher) findViewById(R.id.score_text_switcher);
对findViewById()
的这些调用正在重新初始化切换器,导致他们丢失onCreate()
中的工厂和动画设置,并导致NullPointerException
中的内部setText()
{1}}方法。因为看起来,Switchers在Activity的范围内被声明,你只需要删除那些行。