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

Android应用点击按钮5次后无响应或闪退问题求助

问题描述

开发Android应用时遇到以下问题:

  • 需求:点击按钮5次后进入对应环节;若10分钟内未点击指定TextView,则返回初始按钮点击页面。
  • 异常:运行到该环节时应用无响应或闪退。
  • 使用组件:ImageView、Button、TextView
  • 相关代码:
public void PreparingActivity() {
        Button Hbutton1 = findViewById(R.id.HiddenButton1);
        TextView start = findViewById(R.id.START);
        ImageView logo = findViewById(R.id.Logo);
        if (5 == acceptance) {
            Hbutton1.setVisibility(View.INVISIBLE);
            start.setVisibility(View.VISIBLE);
            logo.setVisibility(View.INVISIBLE);
            for (int i = 0; i < 10; i++) {
                for (int j = 0; j < 60; j++) {
                    start.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            countison = true;
                        }
                    });
                    if (countison) {
                        break;
                    }
                    SystemClock.sleep(1000);
                }
                if (countison) {
                    break;
                }
            }
            if (!countison) {
                start.setVisibility(View.INVISIBLE);
                logo.setVisibility(View.VISIBLE);
            } else {
                acceptance = 0;
                TimerStarts();
            }
        }
    }
  • CPU占用相关日志(部分):

CPU usage from 154450ms to 0ms ago (2023-02-12 10:35:30.281 to 2023-02-12 10:38:04.730):
1.8% 293/android.hardware.bluetooth@1.1-service.sim: 0% user + 1.8% kernel
0.9% 3817/com.example.szamlalo: 0% user + 0.8% kernel / faults: 1755 minor
0.7% 303/android.hardware.graphics.composer@2.3-service: 0% user + 0.7% kernel
0.6% 537/system_server: 0% user + 0.5% kernel / faults: 2140 minor
0.5% 362/surfaceflinger: 0% user + 0.5% kernel / faults: 5 minor
...

问题原因分析
  • 主线程阻塞:代码中用SystemClock.sleep(1000)在主线程循环休眠,Android主线程负责UI渲染和用户交互,长时间阻塞会触发ANR(应用无响应)甚至闪退。
  • 重复设置点击监听:循环中每次给start TextView设置新的OnClickListener,属于冗余操作,还可能引发内存泄漏。
  • 交互逻辑失效:主线程休眠期间,用户点击事件无法被处理,onClick回调根本不会执行,导致countison变量永远不会被置为true,逻辑完全失效。
修复方案

使用Android官方提供的CountDownTimer实现异步倒计时,避免阻塞主线程,同时优化点击事件处理:

private CountDownTimer countDownTimer;

public void PreparingActivity() {
    Button Hbutton1 = findViewById(R.id.HiddenButton1);
    TextView start = findViewById(R.id.START);
    ImageView logo = findViewById(R.id.Logo);

    if (5 == acceptance) {
        Hbutton1.setVisibility(View.INVISIBLE);
        start.setVisibility(View.VISIBLE);
        logo.setVisibility(View.INVISIBLE);

        // 仅设置一次点击监听
        start.setOnClickListener(view -> {
            if (countDownTimer != null) {
                countDownTimer.cancel();
            }
            acceptance = 0;
            TimerStarts();
            start.setVisibility(View.INVISIBLE);
            logo.setVisibility(View.VISIBLE);
        });

        // 初始化10分钟倒计时(总时长10*60*1000毫秒,每秒回调一次)
        countDownTimer = new CountDownTimer(10 * 60 * 1000, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                // 可选:在这里更新倒计时显示,比如start.setText("剩余 " + millisUntilFinished / 1000 + " 秒");
            }

            @Override
            public void onFinish() {
                // 倒计时结束,恢复初始页面状态
                start.setVisibility(View.INVISIBLE);
                logo.setVisibility(View.VISIBLE);
                Hbutton1.setVisibility(View.VISIBLE);
            }
        };
        countDownTimer.start();
    }
}

// 在Activity销毁时取消倒计时,防止内存泄漏
@Override
protected void onDestroy() {
    super.onDestroy();
    if (countDownTimer != null) {
        countDownTimer.cancel();
    }
}

关键优化点

  • 用CountDownTimer替代主线程循环休眠,异步执行倒计时,不阻塞UI交互。
  • 点击监听仅设置一次,避免冗余操作和潜在内存泄漏。
  • 在onDestroy中取消倒计时,确保Activity销毁后定时器不会继续运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 13:51:30