0

I am trying to set a different wallpaper for every home screen, but I get OutOfMemory issues. I have 5 Bitmaps which I am trying to overlay on a wallpaper Bitmap which is 5 times the display width. Using the code below I get OOM. The problem seems to be the first line of code which creates the large wallpaper Bitmap. My question is whether there is a way to do this (i.e. some way that takes up less memory, or someway to allocate more memory??). Thanks!

 Bitmap wallpaper = Bitmap.createBitmap(displayWidth*5,displayHeight, Config.ARGB_8888);
 Canvas canvas = new Canvas(wallpaper);
 Uri data = getIntent().getData();
 Bitmap bmp = getBitmap(data, imagePosition, displayWidth, displayHeight);
 canvas.drawBitmap(bmp, 0, 0,null);
 WallpaperManager wallpaperManager = (WallpaperManager) SetterActivity.this.getSystemService(Context.WALLPAPER_SERVICE);
 wallpaperManager.setBitmap(wallpaper);
 wallpaperManager.suggestDesiredDimensions(bmp.getWidth()*2, bmp.getHeight());
timothyjc
  • 2,188
  • 3
  • 29
  • 54
  • What is the size of your bitmaps? – Sephy Jul 23 '10 at 12:18
  • Well I'm testing on a Nexus One which has a screen size of 480x800. First I create the wallpaper Bitmap which has to be 5 times as big (2400x800). Then for every home screen I will draw another bitmap on the Canvas of size 480x800. – timothyjc Jul 23 '10 at 12:41
  • what are the values of displayWidth and displayHeight? are they the intrinsic width and height? ( myBitmap.getIntrinsicWidth() , myBitmap.getIntrinsicHeight();) – Jorgesys Jul 23 '10 at 18:04
  • The display is 480x800px. I have 5 480x800 (intrinsic dimensions) Bitmaps to set on each of the 5 home screens. – timothyjc Jul 23 '10 at 23:26
  • Hey did you end up finding a solution to this? – Kman Oct 27 '10 at 12:19

2 Answers2

0

If you can't get around having 5 screens worth of images loaded at a time, you could try only having one loaded at a time, and switch based on which home screen is currently being viewed.

That is, you have 2 bitmaps in memory, one is current and one is next. Load the current bitmap on first view. Use onOffsetsChanged to determine when a scroll is happening, and at that point load bitmap next based on which home screen will be showing next. You'll need to do that interpolation from screen A to B on your own. when the scroll is finished, recycle current and save next as current.

I'm sure there are some gotchas in this implementation that I'm not thinking of right now, but you'll only ever have 2 bitmaps allocated with this method. Good luck!

Josh
  • 10,618
  • 2
  • 32
  • 36
0

Bitmap data is allocated in the Native heap (see BitmapFactory OOM driving me nuts for details). How much is available depends on the platform (eg API level 2.2 has 24M Native heap total), but there is no way to grow it beyond that. And how much of the native heap space is allocated depends on what your and other applications are doing with bitmaps/graphics.

Your first line of code / wallpaper bitmap is only 480 * 800 * 32 / 8 = 1.536 Mbytes, which is well within the maximum. So it appears likely that much of the heap is already allocated by the time you get to that line?

Note that the native heap is garbage collected but infrequently - and data is not recovered if the application does not explicitly free it. So if you were running application without recycling your bitmaps (in onDestroy) you might well eat up the Native heap after a few runs.

Community
  • 1
  • 1
Torid
  • 4,176
  • 1
  • 28
  • 29