How to overcome this error: java.lang.OutOfMemoryError: bitmap size exceeds VM budget

I am trying to add images to Sqlite DB and enumerate images from DB to listview .... I save the image path for image acquisition. When I enumerate images from the database on the device, I get an error, for example java.lang.OutOfMemoryError: bitmap size exceeds VM budget

I clear the heap memory every time. How to fix it .. Here is my code.

LView.class

 mySQLiteAdapter = new SQLiteAdapter(this); mySQLiteAdapter.openToWrite(); mAlbum = (ImageView) findViewById(R.id.iv); mAlbum.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { // TODO Auto-generated method stub Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivityForResult(intent, IMG); } }); Button click = (Button) findViewById(R.id.button); click.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mySQLiteAdapter.insert(str); System.out.println(str+" Added"); Intent intent = new Intent(LView.this, MyList.class); startActivity(intent); } });` 

`

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); switch(requestCode) { case 1: if(resultCode == RESULT_OK) { Uri selectedUri = data.getData(); str = getPath(selectedUri); Bitmap bitmap; try { bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedUri)); mAlbum.setImageBitmap(bitmap); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } break; } } } // Converting image path Uri to String path to store in DB public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cur = managedQuery(uri, projection, null, null, null); int columnIndex = cur.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cur.moveToFirst(); return cur.getString(columnIndex); }` 

Pls offer me ... Thanks in advance.

+4
source share
3 answers

1) try to decode the linked image first

You will get the actual image size to prevent OOM problem. Dont ever decode an image first !!!

  BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeByteArray(bitmapByteArray, 0, bitmapByteArray.length, options);' 

options.outWidth and options.outHight are what you want.

2) calculate sample size

using the following code from http://hi-android.info/src/com/android/camera/Util.java.html . If you find that outWidth and outHeight are too large to have an OOM problem, just set outWidth and outHeight to a smaller size. This will give you the approximate size that the decoded image will have for these outWidth and outHeight. The bitmap options here are the same as what you use in step 1.

  private static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == IImage.UNCONSTRAINED) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == IImage.UNCONSTRAINED) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == IImage.UNCONSTRAINED) && (minSideLength == IImage.UNCONSTRAINED)) { return 1; } else if (minSideLength == IImage.UNCONSTRAINED) { return lowerBound; } else { return upperBound; } } 

3) Use the calculated sample size

Once you get the sample size, use it to decode the real image data.

  options.inTempStorage = new byte[16*1024]; options.inPreferredConfig = (config == null)?BitmapUtil.DEFAULT_CONFIG:config; options.inSampleSize = BitmapUtil.computeSampleSize(bitmapWidth, bitmapHeight, bitmapWidth < bitmapHeight?targetHeight:targetWidth, bitmapWidth < bitmapHeight?targetWidth:targetHeight, 1); options.inPurgeable = true; options.inInputShareable = true; options.inJustDecodeBounds = false; options.inDither = true; result = BitmapFactory.decodeByteArray(bitmapByteArray, 0, bitmapByteArray.length, options); 

~ If this is still a problem with OOM, you can try to reduce outWidth and outHeight. bitmap uses the built-in heap, not the java heap. Therefore, it is difficult to determine how much memory is left to decode a new image.


~~ If you need to set outWidth and outHeight too low, then you might have a memory leak somewhere in your code. try freeing up any object from memory that you are not using. eg bitmap.release();


~~~ above is just a sample code. adjust what you need.

+9
source
+2
source

Have you tried using a single bitmap in the class and redistributing it in your case?

0
source

All Articles