3

I have an Android app which loads about 30 Bitmaps into memory. These are jpg resources which are 455x320 px.

This works on all devices I've tested from a G1 to a Galaxy Nexus.

I have another version of this app which is a LiveWallpaper. It works on a Nexus One, Milestone, Galaxy S2, and some 3.x tablets. However, the LWP version of my app crashes with OutOfMemory errors only on the Galaxy Nexus (on ICS).

The following is a simplified version of the code I'm using:

Bitmap bitmap = BitmapFactory.decodeResource(
  lwpService.getResources(), R.drawable.somepic);
imageCache.put(R.drawable.somepic, bitmap);
bitmap = BitmapFactory.decodeResource(
  lwpService.getResources(), R.drawable.someotherpic);
imageCache.put(R.drawable.someotherpic, bitmap);
… // and so on for 30 more images.

Here is the stack trace from logcat:

02-12 00:07:34.456 E/dalvikvm-heap( 6938): Out of memory on a 583696-byte allocation.
02-12 00:07:34.456 I/dalvikvm( 6938): "Thread-7378" prio=5 tid=16 RUNNABLE
02-12 00:07:34.456 I/dalvikvm( 6938):   | group="main" sCount=0 dsCount=0 obj=0x4186c3f8 self=0x20e538
02-12 00:07:34.456 I/dalvikvm( 6938):   | sysTid=7115 nice=0 sched=0/0 cgrp=default handle=2213784
02-12 00:07:34.456 I/dalvikvm( 6938):   | schedstat=( 0 0 0 ) utm=6907 stm=504 core=1
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.nativeCreate(Native Method)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createBitmap(Bitmap.java:605)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createBitmap(Bitmap.java:551)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:437)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.finishDecode(BitmapFactory.java:524)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:499)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:351)
02-12 00:07:34.456 I/dalvikvm( 6938):   at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:374)
02-12 00:07:34.463 I/dalvikvm( 6938):   at com.myapp.loadImage(MyApp.java:155)

Has anybody else had issues loading multiple Bitmaps into memory in a LWP on a Galaxy Nexus?

EDIT: I have found a way to avoid the OutOfMemoryErrors: since my specific images are opaque, I don't need an alpha channel, so I can use Bitmap.Config.RGB_565 instead of Bitmap.Config.RGB_8888. This way, my images are using half the memory as previously.

BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.RGB_565;    
Bitmap bitmap = BitmapFactory.decodeResource(
    lwpService.getResources(), R.drawable.somepic, options);

I don't think this solution would scale for more or larger images, so I'd still be interested in other comments.

Carmen
  • 1,574
  • 17
  • 18

1 Answers1

0

Well, your solution reduced the memory footprint by half (4 bytes on RGB_8888 to 2 bytes on RGB_565). But the real problem here is why you need to load all images at same time? Average home screen dimensions on a live wallpaper is 960 x 800, so what is the reason for loading 30 455x320 images? It does not fit, and even if this solution works on most phones, you are using a huge amount of memory. I would recommend you to load the images dinamically using a pool of bitmaps and recycling it. Cheers!

Rodrigo Dias
  • 412
  • 4
  • 13
  • The reason for the 320x455 resolution images is that this was originally an app on the G1, which I later adapted to a live wallpaper. The reason there are 30 images is that they are used in various animations. I tried not loading and caching them, but the animations became quite slow. I tried only loading and caching the specific images for a given animation, but still had OOM errors. I'm afraid that with a pool of images, it might be difficult to find the optimum size: too large and I'd get OOM errors, too small and I'd have choppy animations. – Carmen Feb 12 '12 at 22:56
  • There may be a way for me to optimize my code (other than the solution I already found). But what's puzzling to me, is that the same logic works on 2.x and 3.x, but not on 4.x. – Carmen Feb 12 '12 at 23:00