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

Android中CountDownTimer顺序执行及循环轮次实现方案问询

解决Android CountDownTimer顺序执行及轮次重复问题

问题根源

你用while循环的方式完全错误,因为CountDownTimer是异步执行的,主线程的while会持续阻塞UI线程,而且异步更新的状态变量无法被while实时感知,自然没法保证时序正确。

可行方案:利用回调链式启动

核心逻辑是在前一个计时器的onFinish()回调里启动下一个计时器,同时维护轮次计数,控制最后一轮是否跳过休息阶段。

以下是完整的实现代码:

package com.example.empty_tv_test;
import android.os.Bundle;
import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import android.os.CountDownTimer;
import android.widget.TextView;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    // 配置参数:可根据需求修改
    private static final int TOTAL_ROUNDS = 3; // 总轮次
    private static final long PREPARE_DURATION = 3000; // 预备倒计时时长(3秒)
    private static final long MAIN_DURATION = 7000; // 主计时时长(7秒)
    private static final long REST_DURATION = 8000; // 休息时长(8秒)
    private int currentRound = 0; // 当前执行的轮次

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        textView = findViewById(R.id.textViewTimer);
        // 启动第一轮的预备计时
        startPrepareTimer();
    }

    // 启动预备倒计时
    private void startPrepareTimer() {
        new CountDownTimer(PREPARE_DURATION, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                updateTimerText(millisUntilFinished);
            }

            @Override
            public void onFinish() {
                textView.setText("开始主计时");
                // 预备结束,启动主计时
                startMainTimer();
            }
        }.start();
    }

    // 启动主计时器
    private void startMainTimer() {
        currentRound++;
        new CountDownTimer(MAIN_DURATION, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                updateTimerText(millisUntilFinished);
            }

            @Override
            public void onFinish() {
                textView.setText("主计时结束");
                // 判断是否是最后一轮
                if (currentRound < TOTAL_ROUNDS) {
                    // 非最后一轮,启动休息计时
                    startRestTimer();
                } else {
                    // 最后一轮,结束整个流程
                    textView.setText("所有轮次完成");
                }
            }
        }.start();
    }

    // 启动休息计时器
    private void startRestTimer() {
        new CountDownTimer(REST_DURATION, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                updateTimerText(millisUntilFinished);
            }

            @Override
            public void onFinish() {
                textView.setText("休息结束,进入下一轮");
                // 休息结束,启动下一轮的预备计时
                startPrepareTimer();
            }
        }.start();
    }

    // 统一更新计时器文本
    private void updateTimerText(long millisUntilFinished) {
        NumberFormat f = new DecimalFormat("00");
        long hour = (millisUntilFinished / 3600000) % 24;
        long min = (millisUntilFinished / 60000) % 60;
        long sec = (millisUntilFinished / 1000) % 60;
        textView.setText(f.format(hour) + ":" + f.format(min) + ":" + f.format(sec));
    }
}

关键说明

  • 链式启动:每个计时器的onFinish()负责启动下一个阶段,完全保证时序顺序,不会出现并行执行的问题
  • 轮次控制:用currentRound跟踪当前轮次,主计时结束后判断是否需要启动休息阶段
  • 代码解耦:把三个阶段拆分为独立方法,逻辑清晰,便于后续修改各阶段的行为或时长
  • 主线程安全:CountDownTimer的回调默认在主线程执行,直接更新UI不会有问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 12:10:21