I have a quite simple activity like this :
public class SurvivalActivity extends Activity {
private static final String KEY_LAYOUT_ID = \"SurvivalLayoutI
I'm sorry that the answer of this question wasn't actually possible to have with the elements I gave in my question.
Indeed, as mentioned in another question here: Why are all my bitmaps upsampled 200%?, I put my pictures in the drawable
folder, which, on a xhdpi screen like mine, will cause Android to upsample everything twice (to match xhdpi against mdpi), and will result in a 400% memory usage (twice the width and twice the height so 4 times as many pixels).
One more thing, since I don't want the user to be able to go back (see the finish()
right after the startActivity()
), here's what I put in the onPause()
:
private void unbindDrawables(View view) {
if (view.getBackground() != null) {
view.getBackground().setCallback(null);
}
if (view instanceof ViewGroup) {
for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
unbindDrawables(((ViewGroup) view).getChildAt(i));
}
((ViewGroup) view).removeAllViews();
}
}
This is some code I got here on StackOverflow (for example here: Drawable vs Single reusable Bitmap better with memory?).
Here are my remarks about this code and why every line is important:
setCallback(null)
removes the reference to the activity, so that it can be garbage collected. If you don't do this, all the views will stay in memory.onPause
, because onDestroy
is not guaranteed to be called.System.gc()
.This is the resulting onPause
code, with the main layout of your activity having the id top_layout
:
@Override
protected void onPause() {
super.onPause();
unbindDrawables(findViewById(R.id.top_layout));
System.gc();
}
It might just be that the bitmap you're putting in the ImageView is very large. Here's some things you can try:
Ditch the xml layout and just inflate and display the problematic ImageView or ImageViews and see if this way you're getting the error.
Also check each of your images to see what size they actually have. The size they'll take in memory is roughly 4*width*height (in bytes, where width and height are the image's size in pixels).
Since your Bitmap instances are taking up memory on the heap, I'm imagining you're using Android 3 or above. In these versions that's where Bitmap instances go (just like any other Java instance). In Android 2.x and below, Bitmap instances were allocated in some offheap memory. Knowing this, make sure that that high heap usage you're getting is indeed from the images, and not from some other instances that are created a lot. Try debugging your constructors and see who calls what when the app starts/runs.
As per Bicou's observations, you might want to manually load your images via BitmapFactory, and in doing so maybe downsample them (via the Options object). Also, try keeping a counter of how much image bytes in memory you total by incrementing with 4*width*height of each image you're actually loading into a Bitmap Object.
The best way to optimize memory usage with bitmaps in your case is to save a list of your ImageViews make this before call finish() for every ImageView:
((BitmapDrawable) myImageView.getDrawable()).getBitmap().recycle();
myImageView = null;