Search code examples
androidbitmapgarbage-collectionimageviewbitmapfactory

Is bitmap can be used after it's been garbage collected?


I was watching this video, that talks about memory allocation for bitmaps and garbage collection:

DevBytes: Bitmap Allocation

Chet is talking about how it was managed by the developer prior to SDK 11 by using .recycle() and after SDK 11 it's is managed by the GC.

To a more practical case currently I'm writing an application that in one of the Activities I create many fragments which basically hold a scroll-able layout of ImageViews. those Images are created from the device camera. So I encountered the OutOfMemory problem and realized that I had to re-size the Images I got from the camera because the result was really high res and took all my application memory.

So now I'm re-sizing and setting the images with very small sizes using this method:

img.setImageBitmap(decodeSampledBitmapFromFile(imagePath, 100, 70));

when decodeSampledBitmapFromFile is:

    public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) 
{ // BEST QUALITY MATCH

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(path, options);

    // Calculate inSampleSize
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        int inSampleSize = 1;

        if (height > reqHeight) {
            inSampleSize = Math.round((float)height / (float)reqHeight);
        }

        int expectedWidth = width / inSampleSize;

        if (expectedWidth > reqWidth) {
            //if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
            inSampleSize = Math.round((float)width / (float)reqWidth);
        }
    options.inSampleSize = inSampleSize;

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;

    return BitmapFactory.decodeFile(path, options);
  }

}

but still I never call .recycle() method on any of the bitmaps because I need them all to be present on screen.

My Questions Are:

1. if I call .recycle() on a bitmap that was already set to an ImageView using setImageBitmap does it mean that it will disappear from the screen or maybe I will receive an exception?

2. If I don't call .recycle() but I'm running my application on Galaxy S3(4.2.1) for example while my application is minSDK is 8. Will the GC kick to do the job for me?

3. In the video he is talking about bitmap reuse using the BitmapFactory object, is there a way to do that prior to SDK 11?


Solution

  • Recycle documentation

    1. I have never used it in this fashion. According to the documentation you're risking an exception
    2. Yes. If you have set all references to your bitmap to null, it will be collected.

      This operation cannot be reversed, so it should only be called if you are sure there are no further uses for the bitmap. This is an advanced call, and normally need not be called, since the normal GC process will free up this memory when there are no more references to this bitmap.

    3. Don't know about bitmap "reuse" in this fashion. Look at the "Managing Bitmap Memory" and "Caching Bitmaps" topics for further information.