0

I am using a listview that displays text and an image. I am trying to use the Task object to download the images asynchronously and load them in the view to have the listview scroll efficiently. But I get OutOfMemoryExceptions often as there are too many Bitmaps in the memory even though I save them to disc and access it. One reason i see is that there are many tasks that are created(for 20 images, 20 tasks are created) and it might also hog the memory. Is there an efficient way to do this?

Here is the code

Rohith
  • 3
  • 2

2 Answers2

1

You have to scale your bitmaps such that they do not get loaded in their full resolution into the memory. A bitmap of 100kb in size is 400kb in the memory as you need to allocate 4bytes per pixel to hold all the color values for Alpha, Red, Green and Blue. If you images are taken with the camera they can easily be 10 times in size and that quickly takes up a lot of memory.

I see you scale the image in DecodeSampledBitmap but then you also need to dispose of it when you are not needing it anymore.

In SetBitmap you forget to dispose of your Bitmap, you can simply put a using statement around it:

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

Please also take a look at the Load Large Bitmaps Efficiently article in the Xamarin docs.

Cheesebaron
  • 24,131
  • 15
  • 66
  • 118
  • Thanks Cheesebaron, I remember trying this before and also just tried. I do not see memory errors but i do not also see the images on the view!! – Rohith Mar 04 '13 at 13:34
  • Also when I tried to do as Xamarin suggests in the Load Large Bitmaps article with bitmap.Recycle, i get this error 03-03 22:45:34.159 E/AndroidRuntime( 3118): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@b393fdf8 03-03 22:45:34.159 E/AndroidRuntime( 3118): at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026) 03-03 22:45:34.159 E/AndroidRuntime( 3118): at android.graphics.Canvas.drawBitmap(Canvas.java:1127) – Rohith Mar 04 '13 at 13:57
0

In addition to loading the bitmaps efficiently, I've recently discovered that it is also important to make sure that Android knows it can release the images later.

One of the decode options available is InPurgeable and setting this to true is important if you want Android to ever clear any loaded Bitmaps from memory.

If this is set to true, then the resulting bitmap will allocate its pixels such that they can be purged if the system needs to reclaim memory. In that instance, when the pixels need to be accessed again (e.g. the bitmap is drawn, getPixels() is called), they will be automatically re-decoded

See:

Community
  • 1
  • 1
Stuart
  • 66,722
  • 7
  • 114
  • 165
  • I will try this one and find out if i dont see the out of memory error. But If I am using bitmapFactory.DecodeStream, will this option help? – Rohith Mar 06 '13 at 04:05