计时器进入负数未跳转至其他Activity,调整if-else后应用崩溃
问题分析与修复方案
你的代码存在两个核心问题,直接导致应用崩溃:
1. 条件判断顺序逻辑完全颠倒
第一个if(seconds == 0)的判断优先级高于倒计时结束的判断分支。当倒计时走到最后一秒(seconds=0且minsTotalTime=0)时,会先进入第一个分支,执行minsTotalTime--让分钟数变为-1,再把seconds设为59——这会导致倒计时永远无法触发结束逻辑,还会让分钟数变成负数,后续逻辑彻底混乱。
2. 子线程中执行UI操作
TimerTask的run()方法运行在子线程中,而Toast.makeText()、startActivity()、finish()都是Android的UI操作,系统禁止在非主线程直接操作UI,这会直接抛出CalledFromWrongThreadException引发崩溃。
修复后的代码示例
private void startTimer(TextView timerTextView) { examTimer = new Timer(); examTimer.scheduleAtFixedRate(new TimerTask() { @Override public void run() { // 优先判断倒计时是否彻底结束 if (seconds == 0 && minsTotalTime == 0) { examTimer.purge(); examTimer.cancel(); // 切换到主线程执行所有UI操作 runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(ExamActivity.this, "Time ran out", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(ExamActivity.this, ExamResults.class); intent.putExtra("correct", getCorrectAnswers()); intent.putExtra("incorrect", getIncorrectAnswers()); startActivity(intent); finish(); } }); } else if (seconds == 0) { minsTotalTime--; seconds = 59; } else { seconds--; } // 如果需要更新计时器文本,同样要在主线程执行 runOnUiThread(new Runnable() { @Override public void run() { timerTextView.setText(String.format("%d:%02d", minsTotalTime, seconds)); } }); } }, 0, 1000); }
关键修复说明
- 调换条件顺序:先判断
seconds ==0 && minsTotalTime ==0,确保倒计时结束的逻辑优先触发 - 所有UI操作通过
runOnUiThread()切换到主线程执行,避免跨线程操作UI的异常
内容的提问来源于stack exchange,提问作者Kuraku
相关产品推荐
相关产品推荐

