Wednesday, March 28, 2012

OutOfMemoryError when using bitmap in Android?


The most common issue that you may face while working with bitmap is OutOfMemoryError. This issue occur because the garbage collector (GC) does not free the object associated with the bitmap and clear preference to pixel data fast enough, thus cause the memory allocated for the bitmap to grow until exceeding Virtual Memory limit.

java.lang.OutOfMemoryError: bitmap size exceeds VM budget
In order to avoid this issue, you need to do recycle() for every bitmap as soon as it no long need. Notice that recycle () is used to free the native object associated with this bitmap, and clear the reference to the pixel data. This will not free the pixel data synchronously; it simply allows it to be garbage collected if there are no other references. The bitmap is marked as “dead”, meaning it will throw an exception if getPixels() or setPixels() is called, and will draw nothing. 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. See the code below:
public class bitmaptest extends Activity {

     @Override
     public void onCreate(Bundle icicle) {
          super.onCreate(icicle);
          // decode a jpg into bitmap
          Bitmap bitmap = BitmapFactory.decodeFile("/sdcard/myimage.jpg");

          ...

          // indicate that the bitmap is no longer need and GC should
          // free it asap
          bitmap.recycle();
     }
}
 
Bimap is a little tricky, miss-use it may causes an exception. Generally using bitmap is recommended only if you need to get detail data of the image such as image width, height, and pixel data. Otherwise, bitmap should not be used in order to avoid OutOfMemoryError. For an example, if you just want to dispaly an image such as icon, you could you ImageView class instead and it also provides various display options such as scaling and tinting. The following code below shows how to build an ImageView that uses an image from drawable resources and add it to the layout.
public class bitmaptest extends Activity {

     private LinearLayout mLinearLayout;

     @Override
     protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);

          // Create a LinearLayout in which to add the ImageView
          mLinearLayout = new LinearLayout(this);

          // Instantiate an ImageView and define its properties
          ImageView imageView = new ImageView(this);
          imageView.setImageResource(R.drawable.my_image);
          imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
          imageView.setPadding(8, 8, 8, 8);
          imageView.setLayoutParams(new GridView.LayoutParams(200, 200));

          // Add the ImageView to the layout and set the layout as
          // the content view
          mLinearLayout.addView(imageView);
          setContentView(mLinearLayout);
     }
}


10 comments:

  1. The US Open Tennis 2020 Live stream will be for the 140th edition of the tournament, which is set to feature many prominent names in the world of tennis.

    ReplyDelete