This lesson teaches you to
- Basic optimization
- Best practices for animations
- Reduce the size of your bitmap assets
- Combine bitmap assets
- Disable anti-aliasing when drawing scaled bitmaps
- Move expensive operations outside the drawing method
You should also read
- Interactive Watch Faces
- Making a performant watch face
- Deprecation of BIND_LISTENER with Android Wear APIs
A watch face runs continuously, so it must use power efficiently.
Additionally, the performance of the watch face should be optimized. Services must not perform unnecessary computations. Watch faces with animations must run smoothly while accommodating notifications and system indicators.
This section contains best practices for improving efficiency.
Color and brightness of a watch face
Dark colors conserve the battery of a watch. The following are recommendations for setting the watch face background, to optimize the watch face's battery use:
- Color. Whenever possible, use a black background.
- Brightness. When a watch face's requirements prevent the
use of a black background, you should strive to keep the brightness of
the background color at or below 25 percent on an
HSV (Hue, Saturation, Value) or HSB scale. For example, if you use the
Colorclass to set the background color, and define the color with the HSV scale, you would use 25 or less for the Value setting (that is, for the brightness setting).
Use callbacks in WatchFaceService.Engine
Ensure that your watch face performs
computations only when active; use callbacks
Preferably, use the following methods of that class to determine if
the watch face is visible:
Alternatively, use the following methods of the same class
Use listeners registered with the DataClient interface
Do not use
WearableListenerService to listen for
events, because it is
called whether or not a watch face is active. For more information, see
Deprecation of BIND_LISTENER
with Android Wear APIs.
Do not register a broadcast receiver in the Android manifest file
to get system events such as time zone changes, battery events, etc., because
is called whether or not a watch face is active. However, you can use the
Context class to register a receiver.
Use dynamic capabilities to interact with the phone
When a watch face requires an operation to run on the phone, that code should only be executed when the watch face is active. The recommended method for letting the app on the phone learn that the corresponding watch face is active is to use the CapabilityClient API.
Define a capability that is dynamically added in the
onCreate() method of
WatchFaceService.Engine. Remove the capability with the
For example, an app that fetches periodic data to display on the watch face should register a listener for the capabilities advertised by the watch face. Add an alarm for fetching updated data and pushing it to the watch face when it is reachable. Remove the periodic alarm if the watch face is no longer selected or the watch went out of reach, was turned off, or otherwise cannot receive the updates.
Monitor power consumption
The Android Wear companion app enables developers and users to see how much battery is consumed by different processes on the wearable device (under Settings > Watch battery).
For information about features introduced in Android 5.0 that help you improve battery life, see Project Volta.
Register encryption-aware watch faces
Android 7.0 and higher include support for file-based encryption and allows encryption-aware applications to run before the user has provided the decryption passcode at bootup. This can reduce the duration of transitioning from boot animation to the watch face by up to 30 seconds.
To enable faster bootup, add
android:directBootAware="true" to the watch face
Note: Use this feature with watch faces that do not use credential encrypted storage.
Best practices for animations
The best practices in this section help to reduce the power consumption of animations.
Reduce the frame rate of animations
Animations are often computationally expensive and consume a significant amount of power. Most animations look fluid at 30 frames per second, so you should avoid running your animations at a higher frame rate.
Let the CPU sleep between animations
Animations and small changes to the contents of the watch face wake up the CPU. Your watch face should let the CPU sleep in between animations. For example, you can use short bursts of animation every second in interactive mode and then let the CPU sleep until the next second. Letting the CPU sleep often, even briefly, can significantly reduce power consumption.
To maximize battery life, use animations sparingly. Even a blinking colon wakes up the CPU with every blink and hurts battery life.
Reduce the size of your bitmap assets
Many watch faces consist of a background image and other graphic assets that are transformed
and overlapped on top of the background image, such as clock hands and other elements of the design
that move over time. Typically these graphic elements are rotated (and sometimes scaled) inside the
method every time the system redraws the watch face, as described in
Draw Your Watch
The larger these graphic assets are, the more computationally expensive it is to transform them.
Transforming large graphic assets in the
method drastically reduces the frame rate at which the system can run your animations.
To improve the performance of your watch face:
- Do not use graphic elements that are larger than you need.
- Remove extra transparent pixels around the edges.
The example clock hand on the left side of Figure 1 can be reduced in size by 97%.
Reducing the size of your bitmap assets as described in this section not only improves the performance of your animations, but it also saves power.
Combine bitmap assets
If you have bitmaps that are often drawn together, consider combining them into the same graphic asset. You can often combine the background image in interactive mode with the tick marks to avoid drawing two full-screen bitmaps every time the system redraws the watch face.
Disable anti-aliasing when drawing scaled bitmaps
When you draw a scaled bitmap on the
Canvas object using the
Canvas.drawBitmap() method, you can provide a
Paint instance to configure
several options. To improve performance, disable anti-aliasing using the
setAntiAlias() method, since this option does not have any
effect on bitmaps.
Use bitmap filtering
For bitmap assets that you draw on top of other elements, enable bitmap filtering on the same
Paint instance using the
setFilterBitmap() method. Figure 2 shows a magnified view of a clock hand with
and without bitmap filtering.
Note: In low-bit ambient mode, the system does not reliably render the colors in the image for bitmap filtering to process successfully. When ambient mode is active, disable bitmap filtering.
Move expensive operations outside the drawing method
The system calls the
method every time it redraws your watch face, so you should only include operations that are
strictly required to update the watch face inside this method to improve performance.
When possible, avoid performing these operations inside the
- Loading images and other resources.
- Resizing images.
- Allocating objects.
- Performing computations whose result does not change between frames.
You can usually perform these operations in the
You can resize images ahead of time in the
Engine.onSurfaceChanged() method, which provides you with the size of the canvas.
To analyze the performance of your watch face, use the Android Device Monitor. In particular,
ensure that the execution time for your
implementation is short and
consistent across invocations. For more information, see
Inspect Threads and Method Traces.