You need to enable JavaScript to run this app. Android Java实现trivia游戏每10秒间隔执行10轮函数加载的最优方案
优惠活动
大模型
产品
解决方案
定价
更多

Android Java实现trivia游戏每10秒间隔执行10轮函数加载的最优方案

核心问题定位
  • 你当前代码中onCreate里的10次循环是主线程同步立即执行的,会在页面创建的瞬间跑完所有playGame()调用,完全没有等待题目展示间隔的环节。
  • 之前使用CountDownTimer失效的原因是,你在这个一次性跑完的循环里循环创建了10个独立的倒计时实例,所有定时器会同时启动,10秒后所有回调同时触发,自然达不到逐题间隔切换的效果。
  • 现有代码存在空指针隐患:在for循环里第一次调用playGame()时,还没有通过findViewById初始化答案按钮、题目文本框的实例,此时方法里操作的控件全是null。
实现方案

核心思路是串行驱动题目流程,不需要一次性加载所有题目:每加载完一题,启动一个10秒的单次延时任务,延时结束后判断是否还有剩余题目,有则加载下一题,没有则跳转游戏结算页。同时要兼容玩家主动点击答案立刻切下一题的场景。

修正后的核心代码

public class GameActivity extends AppCompatActivity {

    // 单题展示时长10秒
    private static final long QUESTION_DURATION_MS = 10_000;
    // 当前题目的序号
    private int questionCount = 0;
    // 全局持有当前题目的倒计时实例,方便后续取消
    private CountDownTimer questionTimer;
    // 界面控件
    private Button answerOneBtn, answerTwoBtn, answerThreeBtn, answerFourBtn;
    private TextView questionTextView;
    // 游戏状态
    private int playerScore = 0;
    private Game currentGame = new Game();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        currentGame.questionList.AnswersJumbled();

        // 提前完成所有控件初始化,避免空指针
        answerOneBtn = findViewById(R.id.AnswerOneButton);
        answerTwoBtn = findViewById(R.id.AnswerTwoButton);
        answerThreeBtn = findViewById(R.id.AnswerThreeButton);
        answerFourBtn = findViewById(R.id.AnswerFourButton);
        questionTextView = findViewById(R.id.questionText);

        // 绑定统一的答案点击事件:点击后取消当前倒计时,立刻切下一题
        View.OnClickListener answerClickHandler = v -> {
            if (questionTimer != null) questionTimer.cancel();
            currentGame.playerOneSelection = ((Button) v).getText().toString();
            // 这里补充答题判分、更新分数的逻辑
            loadNextQuestion();
        };
        answerOneBtn.setOnClickListener(answerClickHandler);
        answerTwoBtn.setOnClickListener(answerClickHandler);
        answerThreeBtn.setOnClickListener(answerClickHandler);
        answerFourBtn.setOnClickListener(answerClickHandler);

        // 游戏启动,加载第一道题
        playGame();
    }

    // 加载单道题目
    public void playGame() {
        currentGame.loadQuestion(questionCount);
        questionTextView.setText(currentGame.currentQuestion);
        answerOneBtn.setText(currentGame.firstAnswer);
        answerTwoBtn.setText(currentGame.secondAnswer);
        answerThreeBtn.setText(currentGame.thirdAnswer);
        answerFourBtn.setText(currentGame.fourthAnswer);

        // 题目加载完成后启动10秒倒计时,超时无操作自动切下一题
        questionTimer = new CountDownTimer(QUESTION_DURATION_MS, QUESTION_DURATION_MS) {
            @Override
            public void onTick(long millisUntilFinished) {
                // 不需要逐秒倒计时显示的话,此方法无需额外逻辑
            }

            @Override
            public void onFinish() {
                // 超时未操作,自动加载下一题
                loadNextQuestion();
            }
        }.start();
    }

    // 统一的切下一题入口,消除重复逻辑
    private void loadNextQuestion() {
        questionCount++;
        // 10题全部加载完成,跳转结算页
        if (questionCount >= 10) {
            // 这里补充跳转到结算页面的逻辑
            finish();
            return;
        }
        // 加载下一道题
        playGame();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        // 页面销毁时取消倒计时,避免内存泄漏
        if (questionTimer != null) {
            questionTimer.cancel();
            questionTimer = null;
        }
    }
}
注意事项
  • 不要把倒计时的创建逻辑放在同步循环里,否则会生成多个同时运行的定时器,造成回调并发触发。
  • 答题切题、超时切题走统一的入口方法,避免逻辑分散出现bug。
  • 页面销毁时必须取消正在运行的倒计时,否则会因倒计时回调持有Activity引用引发内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.26 13:24:01