Android WindowLeaked问题求助:AsyncTask跳转Activity时进度对话框泄漏
解决AsyncTask中ProgressDialog导致的WindowLeaked问题
Hey Derrick, 这个WindowLeaked的坑我之前踩过好多次!本质原因很简单:你的ProgressDialog绑定了当前的Activity,但你在跳转新页面的时候,没先把这个Dialog彻底关闭,导致它还“挂”在已经要被系统回收的原Activity上,自然就抛出泄漏错误了。加延迟根本没触碰到核心问题,咱们来一步步解决:
核心修复步骤
在
onPostExecute里先关Dialog再跳转
这是最关键的一步!doInBackground执行完后,一定要先确保ProgressDialog被关闭,再启动新Activity。还要加判断避免空指针或重复关闭:@Override protected void onPostExecute(Void result) { super.onPostExecute(result); // 先处理Dialog if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); progressDialog = null; // 置空防止后续无效引用 } // 再执行跳转 Intent intent = new Intent(YourCurrentActivity.this, TargetActivity.class); startActivity(intent); // 可选:如果不需要原Activity留在返回栈,加上finish() finish(); }在Activity生命周期销毁时兜底关闭Dialog
万一Activity意外销毁(比如旋转屏幕、系统回收),而AsyncTask还在后台跑,这时候Dialog也会泄漏。所以要在onDestroy里加兜底逻辑:@Override protected void onDestroy() { super.onDestroy(); // 清理Dialog if (progressDialog != null && progressDialog.isShowing()) { progressDialog.dismiss(); progressDialog = null; } // 同时取消正在运行的AsyncTask(如果需要的话) if (yourAsyncTask != null && yourAsyncTask.getStatus() == AsyncTask.Status.RUNNING) { yourAsyncTask.cancel(true); } }规范ProgressDialog的显示时机
记住:所有UI操作都不能放在doInBackground里,ProgressDialog应该在onPreExecute中初始化并显示:@Override protected void onPreExecute() { super.onPreExecute(); progressDialog = ProgressDialog.show(YourCurrentActivity.this, "提示", "正在加载...", true); }
额外注意事项
- 不要使用静态的ProgressDialog,也不要让Dialog持有Activity的强引用(如果你的AsyncTask是静态内部类,记得用弱引用持有Activity,但普通内部类只要按上面的步骤清理就没问题);
- 不要在
doInBackground里做任何UI相关操作,包括更新Dialog进度(要更新的话用onProgressUpdate)。
按照这个流程来,你的WindowLeaked问题肯定能解决!
内容的提问来源于stack exchange,提问作者Derrick Feehi
相关产品推荐
相关产品推荐

