最近开发中,使用 AsyncTask + ProgressDialog 显示进度信息,但在AsyncTask停止,Activity finish 后该Activity的实例始终不会被gc,多次运行程序后,会存在多个activity,造成内存泄漏。 下面详细分析一下:
一份显示进度条的测试代码:
public class Main extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView tv = new TextView(this);
tv.setText("Init State");
setContentView(tv);
tv.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
showProgress(Main.this);
}
});
}
public void showProgress(final Activity activity) {
new AsyncTask<Void, Void, Void>() {
ProgressDialog progressDial;
protected void onPreExecute() {
progressDial = new ProgressDialog(activity);
progressDial.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDial.show();
};
@Override
protected Void doInBackground(Void... params) {
doSomeHeavyWork(progressDial);
return null;
}
protected void onPostExecute(Void result) {
progressDial.dismiss();
};
}.execute();
}
void doSomeHeavyWork(ProgressDialog progress) {
try {
for (int i = 1; i <= 10; ++i) {
progress.setProgress(i);
Thread.sleep(1000);
}
} catch (Exception e) {
}
}
}
上述代码发生内存泄漏的地方在 doSomeHeavyWork() 的 progress.setProgress(i); 部分;我们看一下setProgress()的实现,最终会调用ProgressBar 类的如下方法:
private synchron

本文探讨了在Android中,非UI线程使用View.post()可能导致的内存泄漏问题。当ProgressDialog未正确附加到窗口时,由于静态引用链,导致Activity无法被垃圾回收,从而引起内存泄漏。解决方案包括在AsyncTask开始时添加短暂延迟或使用精确的检查机制。此问题不仅限于ProgressBar,所有非UI线程中对未附加视图调用post()的情况都可能存在类似风险。
最低0.47元/天 解锁文章
1453

被折叠的 条评论
为什么被折叠?



