android.view.ViewRoot $ RunQueue $ HandlerAction предотвращает сбор мусора в Dialog - PullRequest
1 голос
/ 10 октября 2011

В настоящее время я создаю приложение для Android, которое будет работать только на планшетах.Одной из функций является отображение списка событий в (созданном пользователем) диалоговом окне.

В некоторых случаях, когда пользователь подтверждает эти события, диалоговое окно не подвергается сборке мусора, и после открытия диалогового окна несколько раз,количество экземпляров диалогового окна, которые хранятся в памяти, увеличивается и увеличивается.

Поскольку приложение будет работать в течение длительного времени, я предполагаю, что это приведет к проблемам с памятью.

Так что явзял дамп памяти и запустил анализатор памяти Eclipse (MAT).У меня никогда раньше не было подобных проблем, и я не слишком знаком с MAT, но вот что я предполагаю:

Я вижу, что есть несколько экземпляров моего диалога и некоторый "внутренний класс" (MyDialog $ 1)все еще там.Для всех остальных «внутренних классов» (MyDialog $ 2, MyDialog $ 3, ...) счетчик равен 0.

Использование «Объединить кратчайшие пути к корням GC» с опцией «со всеми ссылками» приводит меня к Android.view.ViewRoot $ RunQueue $ HandlerAction, поэтому я предполагаю, что каким-то образом есть ссылка на одного из моих слушателей?

Я надеюсь, что вы можете сказать мне, верно ли мое предположение (и мой способ анализа),И, надеюсь, вы можете дать мне решение или подсказку, как это решить.

Заранее спасибо, Свен

1 Ответ

1 голос
/ 05 ноября 2011

Я думаю, что вы правы в своем предположении.Слушатель, который является анонимным классом, будет иметь ссылку на включающий класс.Вы должны отменить регистрацию слушателей, когда хотите, чтобы диалоговое окно было уничтожено.

В качестве альтернативы, вы можете рассмотреть возможность использования API для обработки жизненного цикла диалога.Устаревшие Activity.showDialog и Activity.removeDialog должны удалить все ссылки на диалоговое окно при его удалении.

В Android 3.0 и выше вы можете использовать DialogFragment вместо Dialog, и FragmentManager должен обрабатывать его жизненный цикл для вас.См. Фрагменты Руководство разработчика.

...