To provide the best possible battery life of Wear OS devices, the system performs a memory usage calculation. As part of the Wear OS app quality guidelines, watch faces that use the Watch Face Format have limits on the amount of memory that they can consume, depending on the watch's current state:
- In ambient mode, the watch face can't consume more than 10 MB of memory.
- In interactive mode, the watch face can't consume more than 100 MB of memory.
System calculates a watch face's memory usage
To compute the size taken up by an image or bitmap font within a watch face that uses the Watch Face Format, the system completes the following steps:
- Decompresses the image or bitmap font.
- Examines the image or bitmap font to see if it can be optimized in one of
the following ways:
- Resized to better match its display size.
- Cropped to remove fully transparent pixels.
- Downsampled to RGB565, if this can be done without loss of fidelity.
Based on the resulting bounding box, the system computes the size of the image or bitmap font, in bytes, as one of the following:
- For images and fonts that use RGBA8888: \( 4 \times width \times height \)
- For images and fonts that use RGB565: \( 2 \times width \times height \)
- For images and fonts that use the ALPHA_8 bitmap configuration: \( width \times height \)
Interactive mode
When calculating memory usage for interactive mode, the system calculates the sum of the following:
- The unprocessed size of any vector fonts.
- The estimated usage of the system's default font.
- The total size of the images and bitmap fonts after any cropping, resizing, or reformatting has been applied.
Configurations
For watch faces that contain configurations, the system attempts to compute the total size of the resources used in the different configurations. Occasionally, when there's a very large number of combinations, the system slightly overestimates how many resources are used simultaneously across the different configurations.
Ambient mode and layers
For ambient mode, the system assumes that the watch is rendered using up to three full screen layers, two of which are completely static:
- Everything underneath the watch elements. Most of the watch face's "body" is composited into this layer. It doesn't matter how many images are used to draw this layer; the system counts it as one full-screen image.
- Any watch hands, digital display, or complications with platform bindings that are rendered dynamically.
- All elements that are listed after the watch hands and complications in the source XML file.
Typically, most memory usage in ambient mode comes from bitmap fonts, especially large ones.
Methods of reducing memory usage
By following the suggestions in this sections, you're more likely to create a watch face whose memory consumption stays within these limits.
Crop and resize bitmap fonts
Crop your images and BitmapFont
objects, and resize them to match their
display size.
When Wear OS draws a watch face, all images are decompressed. A full-screen image that's mostly blank might consume 3 KB on disk, but if it's displayed on a 450-pixel x 450-pixel screen, the system decompresses the image, increasing the image's size in memory to 750 KB or larger.
Use consistent bitmap font heights
When using a BitmapFont
, all images for a character should each have the same
height. Likewise, all images for words should each have the same height.
Use consistent frame sizes in animations
Instead of moving an image across a watch face, update the elements within the image and keep its bounding box in the same location relative to the watch face. For example, if you want to animate a circle on your watch face, consider changing the color of a circle instead of rolling the circle across the watch face.
This technique reduces the size of the bounding box that the system calculates for the animation.
Deduplicate images
If your watch face displays multiple copies of the same image, include only one copy of that image in your resources directory, and reference it multiple times.
Show progress using arcs
To emulate a progress bar that completes after 1 minute or after 1 hour, don't
use 60 separate images. Instead, create an Arc
object that contains an
expression controlling its length, as shown in the following code snippet:
<PartDraw angle="0" width="400" height="400" name="ProgressBar" pivotX="0.5" pivotY="0.5 x="40" y="40"> <Arc centerX="200" centerY="200" width="400" height="400" startAngle="0" endAngle="360"> <!-- Completes a "progress loop" every minute. --> <Transform target="endAngle" value="0 + (clamp([SECOND], 0, 60) - 0) * 6" /> <Stroke cap="ROUND" color="#123456" thickness="10" /> </Arc> </PartDraw>
To display a non-continuous line, for example to achieve a retro digital watch
style look, use either a dash property for a Stroke
object or a
semi-transparent mask image overlay.
Place watch hands and complications at the end of the source file
XML nodes are drawn in the order that they're listed in the source XML file. By putting the watch hands and complications at the end of the file, the system eliminates an entire layer from the ambient mode memory calculation.
Evaluate the memory usage of your watch face
To measure the memory usage of your watch face, use the memory footprint
evaluator tool, available in the watchface
repository on GitHub.