use*_*973 5 java android garbage-collection android-asynctask android-activity
这是一个让我有点失踪的示例代码:
package com.leak;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
public class WindowLeakActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new LeakThread().execute();
}
class LeakThread extends AsyncTask<Void, Void,Void>{
ProgressDialog dialog;
@Override
protected void onPreExecute() {
dialog=new ProgressDialog(WindowLeakActivity.this);
dialog.show();
}
@Override
protected Void doInBackground(Void... params) {
try {
Thread.sleep(2000);
finish();
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
//that would be ok
if(WindowLeakActivity.this!=null && !WindowLeakActivity.this.isFinishing())
dialog.dismiss();
}
}}
Run Code Online (Sandbox Code Playgroud)
如您所见,我创建了一个LeakThread并在doInBackground()方法中完成了WindowLeakActivity.
为了防止窗口泄漏错误,我必须检查Activity是否已经在onPostExecute()方法完成.这让我有点失踪.我有以下问题:
- 是否有Activity实例isFinish()检查onPostExecute是否安全?如果我的Thread类不是Activity.Do的内部类,我必须先检查Activity实例是不是null?
- Activity实例何时会死?作为Activity的生命周期描述,当回调调用onDestroy()时它会终止.但是,Activity的Thread仍在继续.虽然它的窗口不可见,但我也可以得到它的实例.
- 如果我调用System.gc().它会收集Activity的实例吗?
很抱歉我的描述不好.谢谢你非常喜欢读我的问题.
1) 一般来说,避免在 doInBackground() 内使用任何对活动的引用。管理 AsyncTask 以及 Activity 的生命周期是很棘手的。查看此 StackOverflow 线程,了解有关 AsyncTask 及其陷阱的精彩讨论。
2)您无法控制活动实例何时终止,因此不要依赖它。Activity实例的销毁取决于几个因素,这些因素是由系统决定的。因此,请尝试确保不在活动对象本身范围之外的任何地方使用对活动的引用。但是,当您的Activity 的执行即将停止时,您确实会收到回调,因此请确保清理那里的内存。
3) System.gc() 更像是对 JVM 的请求,要求它在方便的情况下尽快运行垃圾收集器。看看这个线程。
从个人经验来看,我可以告诉你,在使用 AsyncTask 时尽量避免使用 ProgressDialog。管理起来很痛苦,很容易泄漏你的 Window 对象,一旦你的设备配置发生变化,应用程序就会崩溃,并且几乎让你很难调试它。我什至还没有看到 Android 上的 Google 应用程序完美地利用 ProgressDialog(直到 Gingerbread ie )。但这只是我的经验。