High resolution Image - OutOfMemoryError
Three hints which should help you:
Use this to load your images, from Loading Large Bitmaps Android documentation:
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;
}Make sure you have only one instance of your
Bitmap
in memory. After displaying it, callrecycle()
and set your reference tonull
. You can use Memory Allocation Tracker to see what is allocated. You can also read HPROF files, as suggested in comments.By default
ARGB_8888
pixel format is used, which means 4 bytes per pixel. Very good article: Bitmap quality, banding and dithering. Your image is JPEG, so it doesn't have transparency, so you are wasting 1 byte on every pixel for alpha channel. It's not very probable, but maybe with acceptable quality you can use even more economical format. Take a look at them. MaybeRGB_565
for example. It takes 2 bytes for pixel, so your image would be 50% lighter. You can enable dithering to improve the quality ofRGB_565
.
java.lang.OutOfMemory with large high-resolution images
This article describes pretty well how to create a heap dump and analyze it using Eclipse MAT. This will help you find the most likely suspects for memory leaks pretty quickly.
Again I point you to this great link I found from another SO Question that has tutorials of how to properly over come the problem.
Throwing OutOfMemoryError with large images
The following has worked for me in similar situations:
Android doesn't really free a bitmap after it drops out of scope. Leaving a high memory usage that quite often does not get cleaned.
Keep a handle to the bitmap you are setting
private Bitmap storedBitmap = null;
Change the OnClickListener()
to:
imgTest.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final Bitmap img = decodeSampledBitmapFromDrawable(Test.this,tipoprueba, widthScreen, heightScreen);
imgTest.setImageBitmap(img);
if(storedBitmap != null){
storedBitmap.recycle();
storedBitmap = null;
}
storedBitmap = img;
}
});
Out of Memory Error on High Resolution mobile phones
I got answer for my problem after reading a lot for continuous 3 days finally my problem is solved.
Well, what's happening is that
setBackgroundResource(R.drawable.imageName)
is going to cause Android to first do the
BitmapFactory.decodeResource()
Which will actually do some resampling based on screen density (i.e., automatic density-based resampling for device resolution) which was causing size to grow much and that too for PNG images.
Android takes almost 10 times more space to render PNG then JPG, so it was consuming much space as my application was rending 10-15 PNG images at any activity. Since android doesn't free up space of memory, if your application is running, resulting OOM (Out Of Memory) error to come up.
So what I have done is just put res/drawable
to res/drawable-nodpi/
(to prevent automatic density-based resampling) and I am sorted.
Hope this helps someone else too.
Reference link:
Android background image memory usage
Related Topics
Restrict API Requests to Only My Own Mobile App
Checking Toast Message in Android Espresso
How to Put Gridview Inside Scrollview
Wifi Connect-Disconnect Listener
Lost My Keystore for Uploaded App on Android Market
Android Ci Build: Could Not Find Aapt2-Proto.Jar
Error - Android Resource Linking Failed (Aapt2 27.0.3 Daemon #0)
Exclude a Class from the Build in Android Studio
Losing Data When Rotate Screen
Reading a Specific File from Sdcard in Android
Connect an Android Device to a Web Service on Local Host
Android Image View Pinch Zooming