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

Android蓝牙配对开发:ProgressDialog超时关闭与隐藏控件显示问题咨询

实现方案

问题排查

你现有代码和尝试的方案存在以下问题:

  • Timer运行在子线程,Android不允许子线程直接操作UI(修改控件可见性、关闭Dialog都属于UI操作),执行时会触发崩溃
  • 定时参数配置错误,你调用的t.schedule(tt, 0, 3000)是立即执行、每3秒重复执行,不符合延迟5秒执行一次的需求
  • 原有代码中setContentView、findViewById方法传入的参数多了引号,R类资源是Int类型不是字符串,会直接导致编译报错,需要先移除引号

实现代码

用Android原生的Handler.postDelayed即可实现需求,默认绑定主线程Looper,可直接操作UI,修改后的完整代码如下:

package com.example.ecyclebin;

import androidx.appcompat.app.AppCompatActivity;

import android.app.ProgressDialog;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class SetUpScreen extends AppCompatActivity {
    // 控件初始化
    Button btStart; // 蓝牙扫描按钮
    Button prButton; // 配对按钮
    TextView deviceName;
    ProgressDialog progressDialog;
    // 声明Handler和超时任务,方便后续取消避免内存泄漏
    private final Handler timeoutHandler = new Handler(Looper.getMainLooper());
    private Runnable timeoutRunnable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 移除参数引号
        setContentView(R.layout.activity_set_up_screen);

        // 所有findViewById参数移除引号
        btStart = findViewById(R.id.scan_bt);
        prButton = findViewById(R.id.pair);
        prButton.setVisibility(View.INVISIBLE);
        deviceName = findViewById(R.id.deviceName);
        deviceName.setVisibility(View.INVISIBLE);
        
        btStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 初始化加载弹窗
                progressDialog = new ProgressDialog(SetUpScreen.this);
                progressDialog.show();
                progressDialog.setContentView(R.layout.progress_dialog);
                progressDialog.getWindow().setBackgroundDrawableResource(
                        android.R.color.transparent
                );

                // 定义5秒超时任务
                timeoutRunnable = new Runnable() {
                    @Override
                    public void run() {
                        // 增加状态判断避免空指针崩溃
                        if (progressDialog != null && progressDialog.isShowing() && !isFinishing() && !isDestroyed()) {
                            progressDialog.dismiss();
                            prButton.setVisibility(View.VISIBLE);
                            deviceName.setVisibility(View.VISIBLE);
                        }
                    }
                };
                // 延迟5000毫秒执行超时任务
                timeoutHandler.postDelayed(timeoutRunnable, 5000);
            }
        });

    }

    @Override
    public void onBackPressed() {
        // 按返回键先取消未执行的超时任务
        if (timeoutRunnable != null) {
            timeoutHandler.removeCallbacks(timeoutRunnable);
        }
        if (progressDialog != null && progressDialog.isShowing()) {
            progressDialog.dismiss();
        }
        prButton.setVisibility(View.VISIBLE);
        deviceName.setVisibility(View.VISIBLE);
        super.onBackPressed();
    }

    @Override
    protected void onDestroy() {
        // Activity销毁时取消未执行任务,避免内存泄漏
        if (timeoutRunnable != null) {
            timeoutHandler.removeCallbacks(timeoutRunnable);
        }
        if (progressDialog != null) {
            progressDialog.dismiss();
        }
        super.onDestroy();
    }
}

核心逻辑说明

  • 绑定主线程的Handler执行postDelayed方法,传入5000毫秒延迟参数,实现5秒后自动触发超时逻辑
  • 所有UI操作都运行在主线程,不会触发线程异常
  • 增加了生命周期校验、任务取消逻辑,避免内存泄漏和空指针崩溃

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 23:06:04