Реализация ListAdapter и возможные утечки памяти

У меня очень простая активность:

public class A extends ListActivity implements ListAdapter
{
    @Override public void onCreate(Bundle b)
    {
        super.onCreate(b);
        setListAdapter(this); //no problems without this line
    }
    // etc... (empty implementation ListAdapter interface functions)
}

Когда я запускаю это действие из другого действия:

startActivity(new Intent(this, A.class));

и кнопку куста "назад" (чтобы уничтожить это действие), куча вырастает примерно на 13..15 кбайт и не уменьшается обратно даже после того, как GC отработает.
Когда я снова начинаю и заканчиваю это действие, голова растет все больше и больше.
Для контроля размера кучи я использую DDMS в Eclipse.

Что я делаю неправильно?


person Vladimir    schedule 24.02.2011    source источник
comment
Вы можете попробовать запустить его без отладки. См. этот ответ: stackoverflow.com/questions/3910473/   -  person Nick Farina    schedule 28.07.2011


Ответы (2)


Я действительно призываю вас не реализовывать ListAdapter в том же классе, что и ваша активность. Это не очень хорошая практика программирования, и все руководства по Android создают отдельные классы в качестве адаптеров. Они, конечно, не объединяют адаптер и активность в один класс. Например, рассмотрим руководство по GridView в качестве примера моей точки зрения.

Проблема заключается в том, где вы говорите setListAdapter(this), на мой взгляд. "this" относится к классу ListActivity A, который никоим образом не является адаптером. для правильного использования setListAdapter вы должны передать либо ArrayAdapter, либо создать свой собственный класс адаптера (который реализует ListAdapter и расширяет BaseAdapter) и создает его экземпляр.

Я думаю, что это может решить вашу проблему, поскольку вы устанавливаете адаптер представления для самого действия, которое кажется рекурсивным или своего рода «бесконечным циклом» в какой-то природе.

person Hakan Ozbay    schedule 24.02.2011
comment
Поправьте меня, если я ошибаюсь, но нет никакой разницы между реализацией интерфейса ListAdapter или подклассом BaseAdapter. - person Vladimir; 25.02.2011
comment
P.S. Я имею в виду, что BaseAdapter — это просто пустая реализация интерфейсов ListAdapter и SpinnerAdapter. - person Vladimir; 25.02.2011
comment
Да, это правда, большой разницы между ListAdapter и BaseAdapter нет, только у ListAdapter есть пара дополнительных методов. Я должен был сказать, что реализует ListAdapter или расширяет BaseAdapter в своем ответе. Вам все равно нужно будет поместить это в отдельный класс по причинам, которые я изложил. - person Hakan Ozbay; 25.02.2011

Кэшируете ли вы представления внутри getView() метода реализации ListAdapter? Если ответ да, то кэширование может быть причиной утечек памяти. Например, утечки могут происходить из-за использования статических элементов или View.setTag(int, Object) для хранения представлений.

В любом случае, я рекомендую вам установить плагин MAT, начать и закончить это действие 5-10 раз и проанализировать кучу . После этого вы сможете увидеть просочившиеся объекты и корень просочившихся иерархий объектов.

person Michael    schedule 24.02.2011