Android не хватает памяти - PullRequest
9 голосов
/ 07 апреля 2011

У меня есть список, который показывает миниатюры (маленькие изображения), загруженные на лету из Интернета.В какой-то момент процессу не хватает памяти.Как я могу сказать, что свободная память заканчивается, поэтому я могу прекратить загрузку большего количества изображений?

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

Примечание. Это не утечка памяти, просто множество загруженных растровых изображений.

Спасибо.

Ответы [ 4 ]

27 голосов
/ 13 сентября 2011

1) Вы должны быть вашим собственным браузером.

Загружайте свои пальцы на SDCard, а не храните их в оперативной памяти.Уменьшите / поверните их перед сохранением, чтобы при следующей их загрузке загрузка была «бесплатной» с SDCard, а не дорогой из интернета.(То есть: как и в любом браузере, используйте локальный файловый кеш).

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

Узнайте, как использовать параметр "inSampleSize" дляраспакуйте растровые изображения с разрешением меньше исходного.

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

2) Создайте систему многоуровневого кэша (Bitmap> SDCard> Internets).

Когда вы распаковываете миниатюру, сохраняйте ее в кэш SoftReference.Если вам нужно использовать этот эскиз, попросите его из кэша.Если виртуальной машине требовалось больше памяти, ваш экземпляр SoftReference может возвращать ноль.

Если вы получаете ноль из кэша растрового изображения, проверьте, не вставили ли вы свой URL на SD-карту, и загрузите его вотсюда растровый кеш.

Если вы получили нулевое значение из файловой системы, загрузите изображение из Интернета, сохраните его на SDCard и вставьте в растровый кеш.

3) Освободите ресурсыкоторые не используются.

Таким же образом, убедитесь, что вы удаляете битовые карты из представлений, в которые они были помещены, как только представление за пределами экрана (если ваши представления живут в ListView или другом адаптерена основе элемента, это, по сути, «свободно» от повторного использования элементов View) - Однако, если у вас есть ImageViews, созданные с помощью растровых изображений, и они не отображаются немедленно на экране, вы, вероятно, тратите кучу.

Вы можете просто вызвать setImageBitmap(null); в ImageView, и ссылка на растровое изображение будет отброшена (так что, если единственным указателем является SoftReferenceкогда он не используется).

4) Обратите внимание, в каком потоке вы находитесь.

Помните, что вы должны загружать растровые изображения из потока, не являющегося пользовательским интерфейсом (мыиспользуйте экземпляр Службы, чтобы действовать как очередь запросов о намерениях), и вы должны прикрепить растровые изображения к экземпляру View только в потоке пользовательского интерфейса.

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

5) Обратите внимание на очереди загрузки.

Если вы похожи на нас и у вас полноразмерные изображения thumbs и , вам нужно либо вручную использовать приоритетную очередь, чтобы поместить запросы на изображения перед запросами большого пальца, либо использовать два разных Сервиса (которые ставят в очередь)их отдельные Intents), чтобы загрузить большие пальцы против полных изображений.

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

6) Узнайте у системы, сколько у вас оперативной памяти.

  Debug.MemoryInfo memoryInfo = new Debug.MemoryInfo();
  Debug.getMemoryInfo(memoryInfo);

7) "onLowMemory()" не выполняет то, что вы ожидаете.

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

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

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

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

mig

3 голосов
/ 07 апреля 2011

Я использую SoftReference для хранения растровых объектов.В списке нужны только текущие видимые изображения.Таким образом, мне никогда не нужно беспокоиться о нехватке места.

Минус в том, что когда я вижу изображения, прокручиваю вниз (заставляя некоторые SoftReferences очистить растровые изображения), а затем снова возвращаюсь к тому же месту -изображения загружаются снова: (

Кроме того, SoftReferences очищаются очень быстро. Я ожидаю, что они дольше сохранят внутреннее растровое изображение.

2 голосов
/ 07 апреля 2011

При создании растровых изображений следует использовать inSampleSize параметр BitmapFactory.Options.

Кроме того, некоторые советы в Android: исключение нехватки памяти в приложении Галерея было полезно дляя проверяю доступную память.

0 голосов
/ 07 апреля 2011

Вы можете переопределить метод действия onLowMemory() для пользовательской обработки таких сценариев

...