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
相关产品推荐
相关产品推荐

