从被破坏的活动中回收属性?

时间:2012-01-20 22:49:12

标签: android android-activity android-asynctask ondestroy

我怀疑活动和物品的破坏。

我附上&从AsyncTask分离活动我不会从asynctask更改ArrayAdapter(请参阅代码)。所以,我得到的是附加的多项活动。分离(应该是方向更改),只有一个任务运行并修改一个适配器,而后者又是创建任务的第一个活动中的一个。因此,当我在onCreate()中附加任务时,我只需将适配器设置为保存任务的适配器,然后处理所有值(在示例中只是一个dummie数字列表)。

这怎么可能?我认为onDestroy()会擦除活动本身及其属性,因此在尝试从AsynkTask访问原始活动的ArrayAdapter时会得到一个空指针异常或类似的东西,但下面的代码可以工作!

private static class TestingTask extends AsyncTask<Void, Integer, Void> {

    private TestingActivity mActivity; // extends ListActivity
    private ArrayAdapter<String> mAdapter;
    private boolean mIsFinished;

    private TestingTask(Context activity) {
        attach(activity);
        mAdapter = (ArrayAdapter<String>)mActivity.getListAdapter();
        mIsFinished = false;
    }

    private void attach(Context activity) {
        mActivity = (TestingActivity)activity;
    }

    private void detach() {
        mActivity = null;
    }

    protected Void doInBackground(Void... params) {
        for (int i = 0; i < 100000; i++) {
            publishProgress(i);
        }
        return null;
    }

    protected void onProgressUpdate(Integer... values) {
        if (!isCancelled()) {
            mAdapter.add(values[0].toString());
        }
    }

    // ...
}

这是因为该任务保持对ArrayAdapter对象的活动引用,因此它不会被删除吗?还是别的什么?

我还遇到了另一个“类似案例”,其中我从onRetainNonConfigurationInstance()返回了一个Activity的属性,让我们说A a,它具有对B b的可见性(这是Activity的另一个属性)。然后,当试图通过a访问b实例时,没有问题,我认为我需要一个包装器来保存两个实例(a和b),否则我会在尝试访问b时遇到异常(我这样做)实际上没有保存)。我不知道它是否与前一种情况有关,在这种情况下,我认为实际上不可用的对象存在,可能是因为它们的主动引用导致没有删除?

谢谢!

1 个答案:

答案 0 :(得分:0)

我想我已经找到了这些问题的答案,因为我想知道......它与垃圾收集器和强引用的使用有关。

Understanding weak references文章中,据说:

  

如果一个对象可以通过一系列强引用(强烈可访问)访问,则它不符合垃圾回收的条件。由于您不希望垃圾收集器销毁您正在处理的对象,这通常正是您想要的

在另一篇文章How Gargabe Collection works中解释说:

  

如果一个对象持有另一个对象的引用,并且当您将容器对象的引用设置为null时,子对象或包含对象将自动符合垃圾回收的条件。

所以,我的结论是:

在第一种情况下:由于我在detach()中将活动设置为null,因此没有内存泄漏,除非适配器具有强引用,否则所有对象都可以进行垃圾回收。所以,我理解除非适配器,否则删除它所包含的活动和所有其他对象,这就是我真正想要的。

在第二种情况下:当我在onRetainNonConfigurationInstance()中返回容器对象(A a)并且它具有对(B b)的强引用时,也可以访问b实例,因为它可以通过强有力的参考链。

希望这会有所帮助。如果有人想提出他/她的意见,那将是受欢迎的!