0

I receive big image (png, >30Mb) and create bitmap for it. And get java.lang.OutOfMemoryError. I try to catch such exception:

try {
    Bitmap bmp = BitmapFactory.decodeStream(someStream);
} catch (OutOfMemoryError e) {
    ;
}

With 2.2 SDK it works well. But with 2.3 app fails with uncatched exception. I don't understand, why?

Thanks!

user1312837
  • 1,268
  • 1
  • 11
  • 29
  • 1
    This question asked before might help http://stackoverflow.com/questions/1955410/bitmapfactory-oom-driving-me-nuts – sfk May 31 '12 at 10:17

4 Answers4

6

You're not really meant to catch Errors:

From the Javadoc:

An Error is a subclass of Throwable that indicates serious problems that a reasonable application should not try to catch. Most such errors are abnormal conditions. The ThreadDeath error, though a "normal" condition, is also a subclass of Error because most applications should not try to catch it.

If you get an Error, especially an OutOfMemoryError, it's basically already too late to do anything about it.

Greg Kopff
  • 15,945
  • 12
  • 55
  • 78
  • @user1312837: If you get an Error, (especially an OOM Error), it's basically too late. – Greg Kopff May 31 '12 at 10:22
  • @user1312837 And what are you planning to do after you've caught the error? Note that the only thing you can reliably do there may not allocate any memory whatsoever, which severely limits your options (and considering you probably don't know what the library functions do you call, you can't rely on those either). – Voo May 31 '12 at 10:25
  • @Voo restart app for example without panic system messages. – user1312837 May 31 '12 at 10:28
  • @user1312837 I'd be quite surprised if `startActivity` internally didn't allocate any memory. – Voo May 31 '12 at 10:31
1

you need to re-size bitmap images before you could use them to display. Have a look at this tutorial about how to re-size bitmaps.

EDIT alternatively you could try to save bitmap as file to filesystem using FileOutputStream. Something like this.

byte[] imageData;
FileOutputStream out = new FileOutputStream(file);
out.write(imageData, 0, imageData.length);
out.flush();
out.close();

decode the bitmap something like this, and scale/resize it as specified in above link.

FileInputStream inputStream = new FileInputStream(file);
BitmapFactory.decodeStream(inputStream, null, options);
N-JOY
  • 10,344
  • 7
  • 51
  • 69
  • I get image as inputstream with http request. To resize image i need to make bitmap object before. Am I right? But i can't make bitmap because of outofmemeory error – user1312837 May 31 '12 at 10:26
  • you can try saving bitmap as a file in filesystem using inputstream. and then try to decode that bitmap. – N-JOY May 31 '12 at 10:42
  • it would be much slower.. http://stackoverflow.com/questions/4634172/how-to-know-a-bitmap-size-from-inputstream-before-creating-the-bitmap gives header preload solution – user1312837 May 31 '12 at 10:46
0

30 mb is just too large. I am very surprised that you were able to create a bitmap out of it in an android 2.2 phone. My advice is to use a much smaller image file. In many phones 24-30mb is the memory given to your whole app.

In your case you must be getting an Error such as StackOverFlowError. You cant catch errors,

Akhil
  • 13,888
  • 7
  • 35
  • 39
0

Decode the image to a lower resolution. You're only allowed about 16mb on android. In the worst case, you can choose to increase this setting.

Also, pre-gingerbread GC is different from post-gingerbread. Before it was a stop the world GC with full garbage collection, but after that, the GC became concurrent, allowing partial collection.

Dhruv Gairola
  • 9,102
  • 5
  • 39
  • 43