You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中TimerTask导致App启动即崩溃问题求助

解决计时器App启动崩溃的问题

看起来你遇到的崩溃主要有两个核心问题,我帮你拆解并给出修复方案:

核心崩溃原因分析

  1. 空指针异常(NullPointerException)
    你声明了private Boolean run;(包装类型)但没有初始化,默认值是null。当TimerTask的run()方法执行if(run)时,JVM会尝试把null自动拆箱为boolean类型,直接触发空指针异常,这是App启动就崩溃的主要原因之一。

  2. 非主线程更新UI
    TimerTask是在后台线程执行的,而Android明确禁止在非主线程中操作UI组件(比如你的timerTextView.setText()),这会触发CalledFromWrongThreadException,同样会导致崩溃。

另外你提供的LogCat里的avc: denied { read }警告是系统级别的权限问题,和你的App崩溃无关,是系统进程读取/proc/osrelease时的权限限制,完全不用管它。

修复后的完整代码

我帮你修正了上述两个问题,同时简化了部分计算逻辑:

public class MainActivity extends AppCompatActivity {
    private TextView timerTextView;
    private Button pauseStartBtn;
    private Button resetBtn;
    private Button productiveBtn;
    private CountDownTimer countDownTimer;
    private boolean run = false; // 改用基本类型并初始化默认值
    Timer timer = new Timer();
    private long timeMS = 0;
    private long seconds = 0;
    private long minutes = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        timerTextView = findViewById(R.id.timerTextView);
        pauseStartBtn = findViewById(R.id.pauseStartBtn);
        resetBtn = findViewById(R.id.resetBtn);
        productiveBtn = findViewById(R.id.productiveBtn);
        startUp();
    }

    TimerTask taskUp = new TimerTask() {
        @Override
        public void run() {
            if (run) {
                timeMS++;
                minutes = timeMS / 60;
                seconds = timeMS % 60; // 用取余简化秒数计算
                final String form = String.format("%02d:%02d", minutes, seconds);
                // 切换到主线程更新UI
                runOnUiThread(() -> timerTextView.setText(form));
            }
        }
    };

    public void startUp(){
        timer.scheduleAtFixedRate(taskUp,1000,1000);
    }

    // 记得在Activity销毁时取消Timer,避免内存泄漏
    @Override
    protected void onDestroy() {
        super.onDestroy();
        timer.cancel();
    }
}

额外功能建议

  1. 暂停/启动功能:给pauseStartBtn添加点击事件,切换run的值即可实现:
    pauseStartBtn.setOnClickListener(v -> run = !run);
    
  2. 重置功能:给resetBtn添加点击事件,重置计时数据并更新UI:
    resetBtn.setOnClickListener(v -> {
        run = false;
        timeMS = 0;
        timerTextView.setText("00:00");
    });
    
  3. 倒计时适配:如果后续要实现倒计时功能,推荐使用Android官方提供的CountDownTimer,它本身就在主线程回调,不需要手动处理线程切换,用法更贴合Android开发场景。

内容的提问来源于stack exchange,提问作者Motcho

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 08:57:39