我怀疑活动和物品的破坏。
我附上&从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时遇到异常(我这样做)实际上没有保存)。我不知道它是否与前一种情况有关,在这种情况下,我认为实际上不可用的对象存在,可能是因为它们的主动引用导致没有删除?
谢谢!
答案 0 :(得分:0)
我想我已经找到了这些问题的答案,因为我想知道......它与垃圾收集器和强引用的使用有关。
在Understanding weak references文章中,据说:
如果一个对象可以通过一系列强引用(强烈可访问)访问,则它不符合垃圾回收的条件。由于您不希望垃圾收集器销毁您正在处理的对象,这通常正是您想要的
在另一篇文章How Gargabe Collection works中解释说:
如果一个对象持有另一个对象的引用,并且当您将容器对象的引用设置为null时,子对象或包含对象将自动符合垃圾回收的条件。
所以,我的结论是:
在第一种情况下:由于我在detach()
中将活动设置为null,因此没有内存泄漏,除非适配器具有强引用,否则所有对象都可以进行垃圾回收。所以,我理解除非适配器,否则删除它所包含的活动和所有其他对象,这就是我真正想要的。
在第二种情况下:当我在onRetainNonConfigurationInstance()
中返回容器对象(A a)并且它具有对(B b)的强引用时,也可以访问b实例,因为它可以通过强有力的参考链。
希望这会有所帮助。如果有人想提出他/她的意见,那将是受欢迎的!