I am trying to prevent OutOfMemoryError in my android app. I have read many post but I cannot solve it yet.
The app has activities with background so I think this is the main problem. OutOfMemoryError only occurs in some devices (maybe due to VM heap) and I need to be sure that this error won't produce a crash in any device.
I have recently read about MAT (Memory Analytics plugin), and I have executed it during the app runtime, here you can see the result:
dominator_tree
report
In this activity I have a background for each orientation (home, home_land). Both sizes are the same (190kb, jpg). When I created the HPROF file the activity was in landscape orientation and I hadn't ran the portrait orientation before. What conclusion can I extract about this result in order to get my purpose?
I can add more information if it is necessary
EDIT
I tried to use the method of this page in order to avoid OutOfMemoryError too, but I couldn't get it. This was my code:
decodeFromResource class
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
public class decodeFromResource {
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) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and
// keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) > reqHeight
&& (halfWidth / inSampleSize) > reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
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 Drawable getDecodedDrawableFromResource(Resources res, int resId,
int reqWidth, int reqHeight){
return new BitmapDrawable(res, decodeSampledBitmapFromResource(res, resId, reqWidth, reqHeight));
}
}
onCreate method from the main activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
resources = getResources();
DisplayMetrics metrics = resources.getDisplayMetrics();
layoutHome = (LinearLayout) findViewById(R.id.home_layout);
if (resources.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
layoutHome.setBackgroundDrawable(decodeFromResource
.getDecodedDrawableFromResource(resources, R.drawable.home,
metrics.widthPixels, metrics.heightPixels));
} else {
layoutHome.setBackgroundDrawable(decodeFromResource
.getDecodedDrawableFromResource(resources,
R.drawable.home_land, metrics.heightPixels,
metrics.widthPixels));
}
I had implemented the "Loading Large Bitmaps Efficiently" method only for the background, because apart from this I have only five small buttons with very small size. Should I also need to implement the method for them? Can you see any errors?