AlertDialog.Builder添加1秒自动关闭逻辑后对话框无法显示问题
问题原因分析
问题核心是阻塞了主线程的UI绘制流程,逻辑漏洞如下:
AlertDialog.Builder.show()调用后并不会立刻完成对话框的渲染显示,只是向主线程的消息队列发送了一个对话框绘制任务,需要等主线程空闲时才会执行绘制、最终显示到界面上。- 你使用默认主线程
Handlerpost的Runnable会被加入主线程消息队列,其中的SystemClock.sleep(1000)直接阻塞了主线程1秒,这期间对话框的绘制任务完全无法执行。 - 等到1秒阻塞结束后,立刻执行了
alertDialog.dismiss(),对话框还没来得及绘制就被销毁,自然看不到显示效果。
正确实现方案
不要在主线程直接调用sleep阻塞,改用Handler的postDelayed方法延迟发送dismiss任务,不会阻碍主线程的正常绘制流程:
/** Show progress dialog */ public static View showProgressDialog(Context context) { AlertDialog.Builder builder = new AlertDialog.Builder(context); LayoutInflater inflater = (LayoutInflater) context.getSystemService( Context.LAYOUT_INFLATER_SERVICE ); View dialogView = inflater.inflate(R.layout.window_progress_dialog, null); builder.setTitle(R.string.msg_progress_loading); builder.setView(dialogView); builder.setCancelable(false); builder.setPositiveButton(null, null); final AlertDialog alertDialog = builder.show(); // 用postDelayed延迟1秒执行dismiss,不会阻塞主线程绘制 new Handler().postDelayed(new Runnable() { @Override public void run() { // 增加校验,避免对话框已关闭时调用dismiss出现异常或窗口泄漏 if (alertDialog != null && alertDialog.isShowing()) { alertDialog.dismiss(); } } }, 1000); return dialogView; }
补充注意点
- 如果在Android 12及以上版本使用,建议给Handler构造方法明确传入
Looper.getMainLooper(),避免隐式调用的编译警告。 - 主线程中禁止执行任何阻塞/耗时操作,否则会导致所有UI绘制、用户交互事件都无法响应。
内容的提问来源于stack exchange,提问作者Moses
相关产品推荐
相关产品推荐

