This year though, I thought it would be nice to have another attempt at a good release. It's almost December again, the source code was still waiting on my disk drive and it didn't make sense to keep it there while I've been spending quite some sleepless nights on it, so I started to shape up things for a release.
Because there still had to be at least one nice, new and original feature in the live wallpaper, I decided to spend some extra time on it by adding support for blurry backgrounds, to make the fake frosted window appear more realistic. But I didn't want to stop there. It had to be dynamic and support custom user images as well. And, oh boy.. did that open up a can of worms...
To sum up, here's a list of issues I got into:
- Availability of memory on mobile devices is limited.
- Availability of memory for a background app is even more limited.
- The user can pick a custom image, including very (I mean, very!) large images. And they need to be blurred as well (being an expensive operation, that's not something you'd like to do for big images on a mobile device).
- For realtime sharp to blurry images and the other way around, multiple images have to be saved, but the required amount of memory is usually not available.
- Earlier versions of Android did not quickly release bitmap memory (usually later on, sometimes not at all), making things even harder.
- Repainting of the wallpaper. Repainting multiple background bitmaps and moving elements is slow!
As you can probably guess by now, memory was the biggest issue. For preprocessing the blurry image I used an algorithm to apply a separate vertical and horizontal gaussian blur, which looks much better than a simple box blur. A lens blur would have been nicer, but the image needs to be preprocessed each time when the user loads a new image (not when changing weather patterns), so the gaussian blurring made a nice tradeoff. In addition to that, the blurred image can be saved on a lower resolution and stretched when it needs to be drawn, which proofed to be a great optimisation in terms of memory usage while keeping the visual stuff interesting.
Another important thing to optimize is memory usage while running another app in front of the wallpaper. The (scaled) background image and temp buffer aren't visible here, so the use of memory can be largely cut out by temporarily releasing the Bitmap memory altogether. It appears that Android can quickly save Bitmaps to PNG image files within the internal memory (SD card would be slow), thus it became a possibility to do nice things while looking at the wallpaper and still have all memory available for real apps when switching to one of those.
So that would make up for a nicely behaving live wallpaper background, if it wouldn't be for Android to make things a little odd by adding the requirement of strategically recycling Bitmap memory where possible. Otherwise, the wallpaper would usually run out of memory by loading just two screen sized bitmaps.
While browsing the Google Play Store I've seen lots of live wallpapers that didn't do things "right". They did not release memory, or huge background images were used without even attempting to optimize them. Some of them just randomly black out because they're out of memory, others just crash. With this blog post, I'm hoping (even though I'm no expert by any means) to motivate other developers to take a better look at these things. I love the many great live wallpapers the Play Store has to offer, but have seen them many a times getting ruined (and uninstalled) by the memory usage. Dear fellow developers: please do check your memory and please do release as much of it as you can when you don't need to have these allocations. Thank you!
If you're curious to see the result: you can download the live wallpaper for free from the following location:
A cookie goes to the person who finds the rather big programming mistake I made and tried to hide ;)
Got any questions on how to optimize your own live wallpaper? Feel free to post!