Optimize Window Backgrounds
Many Android™ applications display a bitmap or other image in a Drawable container as a background for an Activity. Using background images can slow down the performance of your application. However, you can take certain steps to optimize window backgrounds.
This article collects tips and samples for doing so. This article also contains many links — some are to videos that you might enjoy watching.
Why optimize?
As Romain Guy (Google Android engineer) explains in Window Backgrounds and UI Speed, an Activity has a default window background that Android creates in addition to the window background you add, usually a MapView, WebView, or another background image.
On Android, the default background is drawn each time a window is refreshed. This affects your application's performance.
The implementation of default backgrounds can vary across devices and Android platforms. To show you how it works on Motorola CLIQ™ and DEXT™, we ran the HelloMapView sample on the device.
We then ran the HierarchyViewer tool on HelloMapView while it was running on the device. The view hierarchy looks like this (we added the comments in red):
The DecorView holds the default window background. As you can see, it's a view Android creates that contains your highest-level layout. The MapView holds the map background that is drawn on top of the default background.
Prescale bitmaps
Background images are scaled (that is, they stretch or shrink) to fit the view. Scaling a background image at runtime is performance expensive, for two reasons. The first is that bilinear filtering is always turned on by default, which is slower but makes images look better. The second is that as of Android 1.5, the Android rendering engine is only implemented in software, so it has no hardware acceleration.
Instead of scaling at runtime, prescale the bitmap using the createScaledBitmap() method in your activity:
originalImage = Bitmap.createScaledBitmap(
originalImage, // bitmap to resize
view.getWidth(), // new width
view.getHeight(), // new height
true); // bilinear filtering
[Google I/O 2009 session, Turbo-charge Your UI: How to Make Your UI Fast and Efficient, Romain Guy]
You can get a reference to the Bitmap object (here, originalImage) using the BitmapDrawable.getBitmap() method. Romain suggests that the last argument, specifying bilinear filtering, should always have the value true, which gives better image drawing results.
Remove the default background
You can also remove the default window background by creating a theme that sets android:windowBackground to @null:
<resources>
<style name="Theme.NoBackground" parent="android:Theme">
<item name="android:windowBackground">@null</item>
</style>
</resources>
[Google I/O 2009 session, Turbo-charge Your UI: How to Make Your UI Fast and Efficient, Romain Guy]
Then, apply the theme to your activity in AndroidManifest.xml:
<activity
android:name="MyApplication"
android:theme="@style/Theme.NoBackground"> <!-- corrected the theme name -->
<!-- intent filters etc -->
</activity>
[Google I/O 2009 session, Turbo-charge Your UI: How to Make Your UI Fast and Efficient, Romain Guy]
Android versions: This tip is necessary for devices running Android 1.5 or earlier, such as Motorola CLIQ and DEXT. It will also improve performance on devices running Android 1.6 or later.
Change the default background
Another tip is to change the default background to match your application's background. By default, the Android framework displays the default background first, when the application starts, followed by your background.
To avoid the effect of loading two backgrounds, set a background image in a theme. The application loads the theme immediately, followed by the background image, which looks the same. This improves your application's perceived startup time.
This example, taken from Romain's Shelves application, uses a background that tiles a small image on a larger background to save memory and disk space. First, create a file that does the tiling (here named res/drawable/background_shelf.xml):
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/shelf_panel"
android:tileMode="repeat" />
[Android Developers Blog, Window Backgrounds and UI Speed, Romain Guy]
Then, create a theme and set android:windowBackground to the file name:
<resources>
<style name="Theme.Shelves" parent="android:Theme">
<item name="android:windowBackground">@drawable/background_shelf</item>
<item name="android:windowNoTitle">true</item>
</style>
</resources>
[Android Developers Blog, Window Backgrounds and UI Speed, Romain Guy]
If you are not tiling the image, you can simply reference the image name in the theme, for example, @drawable/shelf_panel.
Copyright © 2009, Motorola, Inc. All rights reserved except as otherwise explicitly indicated.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
