Утилизация атрибутов от разрушенной деятельности? - PullRequest
1 голос
/ 21 января 2012

У меня есть сомнения по поводу уничтожения действий и объектов.

Пока я присоединяю и отсоединяю действие от AsyncTask, я не изменяю ArrayAdapter из asynctask (см. Код).Итак, я получаю несколько подключенных и отсоединенных действий (должны изменить ориентацию) и только одна задача, выполняющая и модифицирующая ОДИН адаптер, который, в свою очередь, является одним из первых действий, которые создали задачу.Поэтому, когда я присоединяю задачу в onCreate (), я просто устанавливаю адаптер с тем, который содержит задачу, в которой, в свою очередь, обрабатываются все значения (в примере просто список чисел-пустышек).

Как это может быть возможным?Я думал, что onDestroy () удалит само действие и его атрибуты, и поэтому я получу исключение нулевого указателя или что-то подобное при попытке доступа к ArrayAdapter исходного действия из AsynkTask, но приведенный ниже код работает!

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 и поэтому не удаляется?Или это что-то еще?

Я также столкнулся с другим «подобным случаем», в котором я возвратил атрибут Activity из onRetainNonConfigurationInstance (), скажем, A a, который имел видимость над B b (который является еще одним атрибутом Activity).Затем, при попытке доступа к экземпляру b через a, проблем нет, и я подумал, что мне понадобится оболочка для хранения двух экземпляров (a и b), иначе я получу исключение при попытке доступа к b (что я и делаюна самом деле не сохранить).Я не знаю, относится ли это к ширине предыдущего случая, в котором объекты, которые я предполагал недоступными, действительно есть, возможно, из-за активной ссылки на них, которая не вызывает удаления?

Спасибо!

1 Ответ

0 голосов
/ 21 января 2012

Я думаю, что нашел ответ на эти вопросы и, как мне было интересно ... это связано с сборщиком мусора и использованием сильных ссылок.

В Понимание слабых ссылок * 1004В статье говорится, что:

, если объект доступен через цепочку сильных ссылок (сильно достижимых), он не подходит для сборки мусора.Так как вы не хотите, чтобы сборщик мусора уничтожал объекты, над которыми вы работаете, это обычно именно то, что вам нужно

В другой статье Как работает Gargabe Collection объясняется, что:

, если объект содержит ссылку на другой объект и когда вы устанавливаете нулевую ссылку на объект контейнера, дочерний или содержащийся объект автоматически становится пригодным для сборки мусора.

Итак, мой Вывод заключается в следующем:

В первом случае: поскольку я устанавливаю нулевое значение активности в detach(), утечки памяти нет, и все объекты могут быть удалены мусором, если только адаптер не имеетсильная ссылка.Итак, я понимаю, что действие и все другие объекты, содержащиеся в нем, удаляются, если только адаптер, это то, что я на самом деле хочу.

Во втором случае: когда я возвращаю объект контейнера (A a) вonRetainNonConfigurationInstance() и имеет сильную ссылку на (B b), экземпляр b также доступен, потому что он может быть достигнут через цепочку сильных ссылок.

Надеюсь, это будет полезно.Если кто-то еще хочет высказать свое мнение, это будет приветствоваться!

...