这是一个让我有点失踪的示例代码:
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();
}
}}
如您所见,我创建了一个LeakThread并在doInBackground()方法中完成了WindowLeakActivity。
为了防止窗口泄漏错误,我必须检查Activity是否已经在onPostExecute()方法完成。这让我有点失踪。我有以下问题:
- 活动实例isFinish()检查onPostExecute是否安全?如果我的Thread类不是Activity.Do的内部类,我必须先检查Activity实例是否为null?
- Activity实例何时会死?作为Activity的生命周期描述,当回调调用onDestroy()时它会终止。但是,Activity的Thread仍在继续。虽然它的窗口不可见,但我也可以得到它的实例。
- 如果我打电话给System.gc()。它会收集活动的实例吗?
醇>
对不起我的不好描述。非常感谢你阅读我的问题。
答案 0 :(得分:2)
1)通常,通常避免对doInBackground()内部的活动使用任何引用。 管理AsyncTask以及Activity的生命周期充其量是棘手的。请查看this StackOverflow thread以获得有关AsyncTask及其陷阱的详细讨论。
2)你无法控制活动实例何时会死亡,所以不要依赖它。活动实例的破坏取决于若干因素,这些因素由系统决定。因此,请确保不要在活动对象本身范围之外的任何位置使用对Activity的引用。但是,当 Activity的执行即将停止时,确实会收到回调,因此请确保在那里清理内存。
3)System.gc()更像是对JVM的请求,要求它在方便的时候尽快运行垃圾收集器。看看this thread。
从个人经验来看,我可以告诉你,在使用AsyncTask时尽量避免使用ProgressDialog。管理很痛苦,可以很容易地泄漏Window对象,一旦设备配置发生变化就会崩溃应用程序,并且几乎让你试图调试它。我甚至没有看到Android上的Google应用程序完美地使用ProgressDialog(升级姜饼即可)。那只是我的经历。