bonk live wallpaper source code walk-through
This is a a brief walkthrough of the various objects which comprise
the Android bonk live wallpaper along with some general
observations and constraints that drove this particular design and
Live wallpapers are pretty easy to write. However, they're different than plain
old apps in that:
Therefore just keep these following simple rules in mind when you write your wallpaper:
- They're services. Live wallpapers are running all the time.
Little things like minor memory leaks will tend to be compounded over time and could easily
result in Bad Stuff happening.
- They're usually highly graphical. Although a typical Android device tends to fit in your hand, its
screen still represents a ton of memory. Even on a moderately sized device we're talking
a couple of megabytes of screen data.
- A wallpaper needs to be able to survive a power bounce. This isn't some little app
that's started when everything's there. If a power-cycle happens your wallpaper might
start-up in a world where the filesystem isn't mounted and available yet.
- The rendering cycle needs to be fast. Face it, your wallpaper's running in the background,
and people have Important Things to do with their fones, so try to consume few resources
and stay out of the way.
and you should be fine. (Oh, I forgot one: Stay away from the NDK. You probably really don't need to use it anyway.
I know it's tempting, but this will open up a whole world of underlying architecture, compiler, platform, and support
concerns that you don't really need to think about. Unless you're doing some
actual real-time work like controlling a phased-array radar, stick with the Java SDK.)
- Don't use any memory.
- Don't consume any CPU cycles.
- Don't use any threads.
The package consists of two parts:
- bonkwallpaper -- This is the live wallpaper service. It's a service. It's implemented in BonkWallpaper.java,
and you can see it referenced in the manifest file within the service tags.
- BonkSettings -- This is an app which lets users change the wallpaper settings. It's implemented in
BonkSettings.java, and you can see it referenced in the manifest file as an activity.
The Wallpaper Service
The wallpaper service is implemented in these Java files:
(...more coming soon...)
- BonkWallpaper.java -- This is the guy that does most of the work. It tries to mostly stay out of the way
whilst at the same time implementing the Engine inner class. All the screen scribbling happens here in the doNextFrame()
- Bonk.java -- Each of the circles is called a "bonk" so there are many of them. Each bonk has a radius,
an age, a center, and a mass. The wallpaper
creates and destroys them, and it keeps a list of all of them.
- FlashPoint.java -- A FlashPoint is very short-lived. It's created whenever a couple of bonks collide. -- one
for each colliding bonk. There are many FlashPoints. Each bonk keeps a list of all its collisions (and therefore
- SoundManager.java -- There is only one SoundManager. It manages an Android SoundPool and keeps
track of the list of sounds to play when the bonks collide.
The Settings Activity
The settings activity allows users to communicate (via SharedPreferences) with the wallpaper
service and implements choosing various boolean flags (like whether to display circles,
turn sound on/off, &cet),
choosing a background picture (via an Android Intent), choosing colors, and choosing a collision
sound (via Android Intent). When the app runs, and a user modifies a preference,
BonkWallpaper.BonkEngine.onSharedPreferenceChanged() is called to process the change within the
running wallpaper service. The settings activity is implemented in these files:
(...more coming soon...)
- BonkSettings.java -- This is the settings app and implements any behind-the-scenes
fiddling that needs to be done to the SharedPreferences. The various settings are defined
in the settings.xml file.
- ColorPreference.java -- Most settings can be represented by a number or a boolean or a string. Color
needs three numbers, and Android doesn't provide a UI object to handle this, so ColorPreference.java implements
a way to represent red/green/blue color values to the user.
All the utility routines are static (and used mostly for teasing data from the media
content provider database), and they're in:
The SharedPreferences which refer to sounds or pictures are stored as strings, so
we need a way to convert them from their string value (usually either URIs or URLs)
to device filenames or bitmaps. The methods in here are all static, and they serve
to do that conversion by means of Android's content providers. Given a URI of
some picture-file-or-other, return a bitmap of the picture...stuff like that.
oh! that reminds me... There's a problem I ran into when using the camera to form a
background bitmap. The cameras on many of these devices tend to make big pictures.
Way bigger pictures than the screen can display. Say we have a 5 megapixel camera
on a device whose display is FWVGA (480x850)... which is kindof typical. Then
if we consider that we have one byte each of red, green, blue, and alpha, we could end
up with a 20 megabyte camera-generated bitmap that only needs to go into a 1.5
megabyte screen buffer. If we try to read the picture from a file we could easily
end up running out of memory (remember the rule: "Don't use any memory").
BonkUtil.imageFilePathToBitmap() tries to go round this problem by first
finding the smallest bitmap that's still a multiple of 2 and that's bigger than
or equal to the screen resolution. Once it does that it reads the picture data
using inSampleSize to limit the input size. That's prettymuch the only
thing that happens in this file which is not exactly straightforward.
(bonk wallpaper page: www.emirac.net/android)