Activity实例何时会被销毁?

5

这里有一段示例代码让我有些失落:

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。

为了防止窗口泄漏错误,我必须在onPostExecute()方法中检查Activity是否已经完成。这让我有点不确定。我有以下问题:

  1. 在onPostExecute中对Activity实例进行isFinish()检查是否安全?如果我的线程类不是Activity的内部类,我是否需要先检查Activity实例不为null?
  2. Activity实例何时会消失?根据Activity的生命周期描述,当回调调用onDestroy()时,它将终止。但是,Activity的线程仍在运行。虽然它的窗口不可见,但我仍然可以获取它的实例。
  3. 如果我调用System.gc(),它会收集Activity的实例吗?

对不起,我的表述不好。非常感谢您阅读我的问题。


我知道这不是答案,但请查看此链接:http://commonsware.com/blog/2010/09/10/asynctask-screen-rotation.html 在这里,您可以找到一个非常好的例子,说明如何处理AsyncTask与所有这些活动问题。 - ania
谢谢。这是一个好的且安全的AsyncTask模板。 - user890973
1个回答

2

1) 通常情况下,请避免在doInBackground()方法中使用任何对Activity的引用。管理AsyncTask和Activity的生命周期是相当棘手的。查看这篇StackOverflow帖子,了解有关AsyncTask及其缺陷的良好讨论。

2) 活动实例何时销毁并不在您的控制范围内,因此请不要依赖它。活动实例的销毁取决于由系统确定的几个因素。因此,请确保您不在活动对象本身的作用域之外使用对Activity的引用。但是,当您的Activity即将停止执行时,您会收到回调,请确保在那里清理内存。

3) System.gc() 更像是对JVM的请求,要求它尽快运行垃圾回收器。请查看这篇帖子

从个人经验来看,当使用AsyncTask时,请尽量避免使用ProgressDialog。它很难管理,并且很容易泄漏Window对象,当设备配置更改时会导致应用程序崩溃,并且在尝试调试它时会让您感到非常困扰。我甚至没有看到过Android上的Google应用程序完美地利用ProgressDialog(直到Gingerbread为止)。这只是我的个人经验。


非常感谢您的回答!我同意您的观点。使用 ProgressDialog 很痛苦。除了使用它,您有什么好的想法吗? - user890973
ProgressDialog并不是全部都不好,只是我发现在使用AsyncTask时它不太方便。试着使用ProgressBar代替吧,它是一种您可以在布局中包含的视图,然后在处理配置更改时将引用指向新布局中的视图。 - Archit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接