OutOfMemory when loading a large background image

I use android:background to provide a background image for an Android layout.
After entering some images, I get this exception:

 08-24 00:40:19.237: E/dalvikvm-heap(8533): Out of memory on a 36000016-byte allocation. 


how can i use large images as background on android?
can i expand the memory of the application heap? or is it something bad to do?

+7
android image out-of-memory
source share
4 answers

Please take a look at my related question:

High Resolution Image - OutOfMemoryError

Try to minimize memory usage in the application by keeping the background image as small as possible.

This can be done with:

  • crop image to fit screen
  • compress the image further (use, for example, Photoshop) before using it in the application
  • use the method below to load a bitmap.
  • reload the bitmap as soon as you don't need it.
  • make sure you do not store multiple instances in memory
  • set to null after using a bitmap

Make sure that the images you set as the background are loaded correctly (for example, cropped to fit, for example, fit the screen size) and freed from memory as soon as they are no longer needed.

Make sure that there is only one instance of your bitmap in memory. After displaying it, call recycle() and set your link to null.

Here's how you can upload images:

 public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } public static int calculateInSampleSize( BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { // Calculate ratios of height and width to requested height and width final int heightRatio = Math.round((float) height / (float) reqHeight); final int widthRatio = Math.round((float) width / (float) reqWidth); // Choose the smallest ratio as inSampleSize value, this will guarantee // a final image with both dimensions larger than or equal to the // requested height and width. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio; } return inSampleSize; } 

Thanks to Adam Stelmaszczyk for this wonderful piece of code.

+7
source share

I had a similar problem due to background images in layouts. The normal size of the image memory allocation should be a height * width * 4 bytes (in ARGB_8888 mode, default mode).

If you see and allocate 30 MB when showing activity, there must be some problem. Check if you place background images in the picture folder. In this case, the system must scale this image to a certain screen density, causing a large memory overhead.

Solutions:

  • Place a specific version of the background image in each available folder (mdpi, hdpi, xhdpi ...).
  • Place the background image in a special resource folder called "drawable-nodpi". The system will not try to scale the images located in this directory, so only the stretching process is performed and the allocated memory will be expected.

More info in this answer.

Hope this helps.

+5
source share

I had the same problem and fixed it as follows:

Display them using .fit () and .centerCrop (), and Picasso scales the image if it needs to

 ImageView ivLogo = (ImageView) findViewById(R.id.ivLogo); Picasso.with(getApplicationContext()) .load(R.drawable.logo) .fit() .centerCrop() .into(ivLogo); 

If you run out of memory, Picasso just won't display the image, but won't give you an OOM error. Hope this helps!

+3
source share

Is it possible to expand the heap memory of applications?

Yes, you can. Just set android:largeHeap:="true" to your Manifest.xml.

  <application android:name="com.pepperonas.libredrive.App" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:largeHeap="true" android:label="@string/app_name" android:launchMode="standard"> 
+1
source share

All Articles