2

I'm facing the following problem: When my app is destroyed and recreated several times (e.g. by locking and unlocking the screen), it crashes with the following error:

02-01 19:24:12.000: E/AndroidRuntime(22362): java.lang.OutOfMemoryError: (Heap Size=62755KB, Allocated=55237KB)
02-01 19:24:12.000: E/AndroidRuntime(22362):    at android.graphics.Bitmap.nativeCreateScaledBitmap(Native Method)
02-01 19:24:12.000: E/AndroidRuntime(22362):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:744)

Now, I've read several posts about this error and how to fix it but none of them seemed to help so far. So here's how I deal with images in my app: My App has only one activity that looks somewhat like this:

public class MainActivity extends Activity {

static MenuView mv;

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    [...]
    mv = (MenuView) findViewById(R.id.menuview);
    mv.setOnClickListener(new KlickLauscher());
}

public void onDestroy() {
    super.onDestroy();
    mv.destroy(); 
    System.gc();
}

The MenuView looks somewhat like this:

public class MenuView extends View {

MyBitmap button;

public MenuView(Context context, AttributeSet attrs) {
    super(context, attrs);
    initialize();
}

public void initialize() {
     button = new MyBitmap("R.drawable.bitmap1");
}

public void onDraw(Canvas c) {
    c.drawBitmap(button.getBmp(),0,0,mPaint);
}   

public void destroy() {
    button.destroy();
}

And, last but not least, the class MyBitmap looks like this:

class MyBitmap {

Bitmap bmp;

 public MyBitmap(int r) {
  bmp = MyBitmap.createBmp(r);
 }

 public Bitmap getBmp() {
  return bmp;
 }

 static Bitmap createBmp(int r) {
  // Some irrelevant code
  return Bitmap.createScaledBitmap(BitmapFactory.decodeResource(mv.getContext().getResources(),r), width, height, true);
 }

 public void destroy() {
  bmp.recycle();
 }
}

Every single Bitmap in my app is realized using this MyBitmap class, and every single one of them gets recycled when onDestroy() is called. Long story short: Has anyone any idea what else could cause the error?

trincot
  • 317,000
  • 35
  • 244
  • 286
vauge
  • 801
  • 4
  • 14
  • 30
  • onDestroy is not guaranteed to be called. Try recycling in onPause() instead. – Simon Feb 02 '13 at 22:27
  • I've used Log.e(...) to find out when onDestroy is called, and so far, it has always been called when I locked my app. Also, button.getBmp().isRecycled() returns true. – vauge Feb 02 '13 at 22:33
  • OK, see the answer here http://stackoverflow.com/questions/9461364/exception-in-unbinddrawables. The question is not relevant but the answer may be. – Simon Feb 02 '13 at 22:46

1 Answers1

0

Try to downsample the bitmap and use the correct bitmap format according to your needs, as written here.

Also, I think the code in createBmp actually creates 2 bitmaps, so you could recycle the one that you don't use.

Why do you scale the bitmap in the first place? You can set the imageView to scale it instead.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • Thanks for the link! But how to recycle the second bitmap created in createBmp? – vauge Feb 02 '13 at 22:42
  • First , i think you don't need to scale the bitmap at all this way . Second, if you insist of doing so , simply have a reference to the old bitmap (created by decodeResource) and the new one (created by createScaledBitmap ) . After scaling , you can recycle the old one. – android developer Feb 02 '13 at 22:45