Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bitmap OutOfMemoryError

Tags:

android

I have uploaded a new Live Wallpaper up onto the Android Market about a week ago and I am getting quite a few reports of a java.lang.OutOfMemoryError .

This error is happening to smaller phones with not enough memory to load my 1115 by 1000 image as the Live Wallpaper background.

I have tried using inSampleSize, but it scales the background down so much that when I try to scale it back to the normal size it is all pizelated.

Does anyone possibly have an example of how I can fix this problem with my jpg image?

like image 409
Gatekeeper Avatar asked Oct 15 '25 16:10

Gatekeeper


2 Answers

i think that slayton's reply is probably the first thing to address, but you can also save a lot of memory using inPreferredConfig and anything less than ARGB_8888. Try RGB_565:

BitmapFactory.Options bounds = new BitmapFactory.Options();
bounds.inPreferredConfig = Bitmap.Config.RGB_565;
InputStream input = getAssets().open("assets/your-image.jpg");
Bitmap bitmap = BitmapFactory.decodeStream(input, null, bounds);    
like image 119
momo Avatar answered Oct 18 '25 08:10

momo


I have had the same difficult problem in the last few week. I can successfully load 1900 x 1200 bitmaps into my wallaper, but changing images brings outOfMemory errors. This is because when your wallpaper is running it creates a wallaper engine and if you go to its setting then on many androids will create the second PREVIEW engine, so your app will take twice as much memory!

This combined with slow garbage collector (GC) when loading new images will create outOfMemory errors.

The solution I've found is to stop and unload all images from the first engine when the second, preview is started using

bitmap.recyle();
bitmap = null;
System.gc();
try {
  synchronized (this){
     wait(200);
  }
} catch (InterruptedException e) {

}

You need to notify the first engine to stop animation first by creating a boolean preference for that purpose so that engine 1 detects it in onSharedPreferenceChanged and stop its doDraw loop, then you clean up its images. In onCreate in the engine class you can detect if it is a preview mode:

boolean isPreview = this.isPreview();

I am not sure if wait(200) really helps but in theory it should give more time to the system to do its GC... anyway I managed to get rid of outOfmemoryError even on Sony xPeria which is really prone to this type of errors like crazy.

Also, you must avoid creating bitmaps in your animation loop, that is absolute no no. Instead create your slice bitmap when the engine is created and reuse it.

like image 31
Lumis Avatar answered Oct 18 '25 07:10

Lumis



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!