Reputation: 7138
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?
Upvotes: 4
Views: 1297
Reputation: 21629
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.
Upvotes: 1
Reputation: 3935
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);
Upvotes: 2
Reputation: 20319
What phones have a display density of 1115 by 1000 pixels? The correct thing to do is to scale down the wallpaper to the EXACT size of the phone's display. Anything bigger than that is a waste as the phone will result in wasted memory.
Upvotes: 0