2013-03-04 5 views
0

Я использую listview, который отображает текст и изображение. Я пытаюсь использовать объект «Задача» для асинхронного скачивания изображений и загрузки их в представление, чтобы иметь возможность прокрутки списка. Но я часто получаю OutOfMemoryExceptions, так как в памяти слишком много растровых изображений, хотя я сохраняю их на диске и получаю доступ к нему. Одна из причин, по которой я вижу, состоит в том, что создано множество задач (для 20 изображений создано 20 заданий), и это может также вызвать зависание памяти. Есть ли эффективный способ сделать это?Монодид Скачивание изображений эффективно

Вот code

ответ

1

Вы должны масштабировать растровые изображения таким образом, чтобы они не загружаются в их полном разрешении в память. Растровое изображение размером 100 КБ составляет 400 кбайт в памяти, так как вам нужно выделить 4 байта на пиксель, чтобы сохранить все значения цвета для альфа, красного, зеленого и синего. Если вы делаете снимки с помощью камеры, они могут быть легко в 10 раз по размеру и быстро занимают много памяти.

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

В SetBitmap вы забыли выбрасывайте Bitmap, вы можете просто поставить using заявление вокруг него:

using(var bitmap = ImageDownloader.DownloadImage(url, width, height)) 
{ 
    if(!token.IsCancellationRequested) 
     (this.m_context as Activity).RunOnUiThread(
       () => imageView.SetImageBitmap(bitmap) 
      ); 
} 

Обратите также внимание на Load Large Bitmaps Efficiently article в документации Xamarin.

+0

Спасибо Cheesebaron, я помню, как пробовал это раньше, а также просто попробовал. Я не вижу ошибок памяти, но я также не вижу изображения на экране! – Rohith

+0

Также, когда я пытался сделать то, что предлагает Xamarin в статье «Загрузка больших растровых изображений» с помощью bitmap.Recycle, я получаю эту ошибку 03-03 22: 45: 34.159 E/AndroidRuntime (3118): java.lang.RuntimeException: Canvas: пытается использовать переработанную растровую карту [email protected] 03-03 22: 45: 34.159 E/AndroidRuntime (3118): \t at android.graphics.Canvas.throwIfRecycled (Canvas.java:1026) 03-03 22:45 : 34.159 E/AndroidRuntime (3118): \t at android.graphics.Canvas.drawBitmap (Canvas.java:1127) – Rohith

0

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

Один из доступных вариантов декодирования - InPurgeable, и установка этого значения true важна, если вы хотите, чтобы Android когда-либо очищал любые загруженные растровые изображения из памяти.

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

См:

+0

Я попробую это и узнаю, не вижу ли я ошибку в памяти. Но если я использую bitmapFactory.DecodeStream, эта опция поможет? – Rohith