Android ListView Row Background вызывает проблему OutOfMemory - PullRequest
1 голос
/ 05 января 2012

У меня есть фрагмент, который извлекает данные из веб-сервиса и отображает их в ListView. У меня есть 10 различных селекторов, которые могут использоваться для фона строк. Фон повторяется после его зацикливания.

Проблема, с которой я сталкиваюсь, заключается в том, что устройство (Galaxy Nexus!) Не может обрабатывать отображение всех этих фонов. Когда я устанавливаю фон с помощью setbackgroundResource, ОС постоянно вызывает GC для освобождения памяти, что делает прокрутку ListView чрезвычайно прерывистой.

Поэтому я попытался кэшировать используемые Drawables. Я вижу улучшение, но в конечном итоге устройство выдаст исключение OutOfMemory из-за количества кэшируемых объектов Drawables. Чтобы привести пример того, сколько кэшируется, мне нужны все 10 селекторов, которые содержат по два рисованных элемента в каждом, плюс первый и последний, поскольку они различны. Это 24 рисования в памяти.

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

Есть предложения? Я потратил пару дней, работая над этим безостановочно, и не нашел жизнеспособного / близкого решения.

Спасибо

Адам

Ответы [ 2 ]

6 голосов
/ 05 января 2012

Mimminito,

Проблема, которую вы описываете, мучает многих разработчиков на платформе Android.Причина этого заключается в том, что когда Google реализовал View Drawables, они должны были сделать обоснованное предположение о том, что предыдущий Drawable, возможно, необходимо сохранить.Это связано с тем, что все больше и больше приложений на все большем количестве платформ требуют такого поведения.

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

  1. При замене фона получите исходный фон.Если это растровое изображение, recycle() это.Если это Drawable, установите для ссылки нулевое значение и удалите его Обратный вызов с помощью setCallback (Это особенно важно при изменении ориентации или переключении действий).

  2. Графика являетсянаиболее ресурсоемкие ресурсы.Если вы используете Drawable или Bitmap, он использует 4 байта на пиксель.НО, если изображение должно быть изменено для правильного отображения, оно на самом деле использует немного больше, независимо от того, является ли приложение большим или меньшим.Создание графики в высоком разрешении - это здорово, но для мобильных устройств вы хотите масштабировать ее до размеров, которые вы собираетесь использовать.

  3. Если вы используете много графикиВы можете рассмотреть возможность использования только тех, которые будут видны.То есть, если у вас есть 32 элемента, но видны только 3, загрузите только 3 видимых элемента и, возможно, некоторых ближайших соседей.Ленивая загрузка может быть реализована для ряда стандартизированных элементов управления.

  4. Я рекомендую просмотреть файлы .9.png.Они отлично подходят для оптимизации графики.

  5. Если у ваших кнопок есть текст, не рисуйте его в графическом файле.Разрешить Android размещать текст в графическом файле.Его обрабатывают по-разному, и потребление памяти значительно снижается.Хотя это может быть не столь эстетично, но это повысит надежность (вот почему вы здесь)

  6. В некоторых случаях может быть желательно, чтобы графика была плоской, а точнеечем сжатый формат.Это снижает нагрузку на процессор и память, но за счет размера файла.Это связано с тем, что сжатые форматы должны быть распакованы в памяти, чтобы их можно было использовать в любом случае, но память не освобождается до тех пор, пока файл не закроется.(Это даже не включает память для кода времени выполнения, использованного для его распаковки, и даже БОЛЬШЕ дорого, когда приложение должно изменить размер графики).

  7. Установка некоторой дополнительной системыОператоры .gc () могут помочь облегчить загрузку, но они ненадежны, поскольку они только сообщают системе, что она готова к сборке мусора при первой возможности.

  8. Наконец,Вы можете иметь размеры в зависимости от разрешения устройства.Это информация, которую вы можете передать через ваше приложение.Это то, как мы должны поддерживать несколько устройств в локальном приложении.

Все эти предложения могут помочь, но это много информации.Надеюсь, я дал вам достаточно для реализации решения, которое будет отвечать вашим потребностям.

Надеюсь, это поможет, FuzzicalLogic

0 голосов
/ 20 мая 2012

Может быть, вы устанавливаете cacheColorHint на прозрачный (если у вас фиксированное фоновое изображение): android:cacheColorHint="#00000000". Для меня это также многократно вызывало ГК.

Я обнаружил, что установка следующих свойств отключает кеширование представления списка Android, и список прокручивается плавно (GC больше не вызывается так часто):

android:scrollingCache="false"
android:animationCache="false"

Также, если вы хотите избавиться от цвета выбора по умолчанию, используйте это:

android:listSelector="#00000000"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...