The build tools (aapt2) compile AndroidManifest.xml and every
XML file under res/ into Android’s binary XML, often called AXML, and all
simple resources into the resource table resources.arsc. Both are built
from the same chunks. This page follows ResourceTypes.h in
the Android Open Source Project (frameworks/base/libs/androidfw), which is
the format’s only specification. All numbers are little-endian.
Chunk header
Every chunk starts with this 8-byte header (ResChunk_header). A chunk’s
own header may be longer; headerSize says how long, so a reader can skip
fields it does not know, and size lets it skip whole chunks.
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 2 | type | Chunk type, below. |
2 | 2 | headerSize | Size of the chunk’s header, including these 8 bytes. |
4 | 4 | size | Size of the whole chunk, header and data. |
Chunk types
| Type | Name | Meaning |
|---|---|---|
0x0000 | RES_NULL_TYPE | Null chunk |
0x0001 | RES_STRING_POOL_TYPE | String pool |
0x0002 | RES_TABLE_TYPE | Resource table (the whole of resources.arsc) |
0x0003 | RES_XML_TYPE | Binary XML document (the whole of a compiled XML file) |
0x0100 | RES_XML_START_NAMESPACE_TYPE | Start of a namespace mapping (also RES_XML_FIRST_CHUNK_TYPE) |
0x0101 | RES_XML_END_NAMESPACE_TYPE | End of a namespace mapping |
0x0102 | RES_XML_START_ELEMENT_TYPE | Start tag, with its attributes |
0x0103 | RES_XML_END_ELEMENT_TYPE | End tag |
0x0104 | RES_XML_CDATA_TYPE | Text content |
0x017F | RES_XML_LAST_CHUNK_TYPE | Upper end of the XML node range (not a chunk of its own) |
0x0180 | RES_XML_RESOURCE_MAP_TYPE | Resource map: attribute names to resource IDs |
0x0200 | RES_TABLE_PACKAGE_TYPE | A package in the resource table |
0x0201 | RES_TABLE_TYPE_TYPE | The entries of one resource type in one configuration |
0x0202 | RES_TABLE_TYPE_SPEC_TYPE | The specification of one resource type: flags for each entry |
0x0203 | RES_TABLE_LIBRARY_TYPE | Shared library package IDs |
0x0204 | RES_TABLE_OVERLAYABLE_TYPE | A set of resources that runtime resource overlays may replace |
0x0205 | RES_TABLE_OVERLAYABLE_POLICY_TYPE | Which overlays may replace them |
0x0206 | RES_TABLE_STAGED_ALIAS_TYPE | Staged resource IDs mapped to their finalised IDs |
String pool
Every string in a document or table is stored once in a string pool and referred to
by index (a ResStringPool_ref: a uint32 index, with
0xFFFFFFFF meaning none).
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0001, headerSize 28. |
8 | 4 | stringCount | Number of strings. |
12 | 4 | styleCount | Number of style span arrays. |
16 | 4 | flags | 0x001 SORTED_FLAG: strings are sorted. 0x100 UTF8_FLAG: strings are UTF-8, otherwise UTF-16. |
20 | 4 | stringsStart | Offset from the chunk start to the string data. |
24 | 4 | stylesStart | Offset from the chunk start to the style data. |
28 | 4 × stringCount | string offsets | Offset of each string from stringsStart. |
| … | 4 × styleCount | style offsets | Offset of each style from stylesStart. |
UTF-16 strings start with a uint16 length in characters; a length
over 32767 sets the top bit and continues in a second uint16 (high 15 bits first). The
characters follow, then 0x0000. How UTF-8 strings (with
UTF8_FLAG) store their lengths is not described in ResourceTypes.h and is
not confirmed here.
Styles are lists of spans, ResStringPool_span:
name (string index of the tag name), firstChar and
lastChar (uint32 each), each list ended by 0xFFFFFFFF
(END).
Binary XML document
A compiled XML file is one RES_XML_TYPE chunk (headerSize 8) that holds,
in order, a string pool, usually a resource map, and then the nodes in document order.
It begins 03 00 08 00 followed by the file size, then
01 00 1C 00 for the string pool.
Resource map
An optional chunk of type 0x0180 whose data is an array of uint32
resource IDs, mapping strings in the pool back to resource identifiers: entry
i is the resource ID of the attribute named by string i.
Node header
Every node chunk has a 16-byte header (ResXMLTree_node) and then its
extension.
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0100 to 0x0104, headerSize 16. |
8 | 4 | lineNumber | Line in the original XML source. |
12 | 4 | comment | String index of a comment before the node, or 0xFFFFFFFF. |
Namespace start and end (0x0100, 0x0101)
| Offset | Size | Field | Meaning |
|---|---|---|---|
16 | 4 | prefix | String index of the prefix, such as android. |
20 | 4 | uri | String index of the URI, such as http://schemas.android.com/apk/res/android. |
Start element (0x0102)
| Offset | Size | Field | Meaning |
|---|---|---|---|
16 | 4 | ns | String index of the element’s namespace URI, or 0xFFFFFFFF. |
20 | 4 | name | String index of the element name. |
24 | 2 | attributeStart | Offset from offset 16 to the first attribute (normally 20). |
26 | 2 | attributeSize | Size of each attribute (20). |
28 | 2 | attributeCount | Number of attributes. |
30 | 2 | idIndex | 1-based index of the id attribute, 0 if none. |
32 | 2 | classIndex | 1-based index of the class attribute, 0 if none. |
34 | 2 | styleIndex | 1-based index of the style attribute, 0 if none. |
Each attribute (ResXMLTree_attribute, 20 bytes):
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 4 | ns | String index of the namespace URI, or 0xFFFFFFFF. |
4 | 4 | name | String index of the name; its resource ID is in the resource map. |
8 | 4 | rawValue | String index of the original text value, or 0xFFFFFFFF when only the typed value is kept. |
12 | 8 | typedValue | The value as a Res_value. |
End element (0x0103)
| Offset | Size | Field | Meaning |
|---|---|---|---|
16 | 4 | ns | Namespace URI string index, or 0xFFFFFFFF. |
20 | 4 | name | Element name string index. |
Text (0x0104)
| Offset | Size | Field | Meaning |
|---|---|---|---|
16 | 4 | data | String index of the text. |
20 | 8 | typedData | The text as a typed value, if any. |
Typed values (Res_value)
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 2 | size | Size of this structure, 8. |
2 | 1 | res0 | Always 0. |
3 | 1 | dataType | Type of data, below. |
4 | 4 | data | The value. |
| dataType | Name | data holds |
|---|---|---|
0x00 | TYPE_NULL | 0 = undefined (DATA_NULL_UNDEFINED), 1 = explicitly empty (DATA_NULL_EMPTY, written @null) |
0x01 | TYPE_REFERENCE | A resource ID (@type/name) |
0x02 | TYPE_ATTRIBUTE | An attribute resource ID, resolved from the theme (?attr/name) |
0x03 | TYPE_STRING | A string pool index |
0x04 | TYPE_FLOAT | An IEEE 754 single-precision number |
0x05 | TYPE_DIMENSION | A complex number with a dimension unit |
0x06 | TYPE_FRACTION | A complex number with a fraction unit |
0x07 | TYPE_DYNAMIC_REFERENCE | A resource ID in a shared library, whose package ID is assigned at run time |
0x08 | TYPE_DYNAMIC_ATTRIBUTE | An attribute ID in a shared library |
0x10 | TYPE_INT_DEC | An integer, originally written in decimal (TYPE_FIRST_INT) |
0x11 | TYPE_INT_HEX | An integer, originally written in hexadecimal |
0x12 | TYPE_INT_BOOLEAN | 0 or 1 for false or true, as the header describes it (files written by the tools are often seen with 0xFFFFFFFF for true; not confirmed in a source) |
0x1C | TYPE_INT_COLOR_ARGB8 | Colour #aarrggbb (TYPE_FIRST_COLOR_INT) |
0x1D | TYPE_INT_COLOR_RGB8 | Colour #rrggbb |
0x1E | TYPE_INT_COLOR_ARGB4 | Colour #argb |
0x1F | TYPE_INT_COLOR_RGB4 | Colour #rgb (TYPE_LAST_COLOR_INT and TYPE_LAST_INT) |
Complex numbers (dimensions and fractions)
| Bits | Field | Values |
|---|---|---|
| 0–3 | unit | Dimensions: 0 px, 1 dp (dip), 2 sp, 3 pt, 4 in, 5 mm. Fractions: 0 % (of the item itself), 1 %p (of the parent). |
| 4–5 | radix | Where the binary point sits in the mantissa: 0 = 23p0 (integer), 1 = 16p7, 2 = 8p15, 3 = 0p23 (bits before and after the point). |
| 6–7 | — | Unused. |
| 8–31 | mantissa | Signed 24-bit number. |
The value is the mantissa divided by 20, 27, 215 or
223 for radix 0 to 3. Example: 0x00001001 is mantissa 16,
radix 0, unit 1: 16dp.
Resource IDs
A resource ID is 0xPPTTEEEE: package index, type index and entry index;
package and type values start at 1.
Resource table (resources.arsc)
The file is one RES_TABLE_TYPE chunk: its header, a global string pool
holding every string value, then one package chunk per package (normally one).
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0002, headerSize 12. |
8 | 4 | packageCount | Number of package chunks. |
Package (0x0200)
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0200, headerSize 288. |
8 | 4 | id | Package ID, the PP of resource IDs. |
12 | 256 | name | Package name, 128 UTF-16 units, NUL-terminated. |
268 | 4 | typeStrings | Offset to the string pool of type names (attr, drawable, layout, string…). |
272 | 4 | lastPublicType | Last index into typeStrings that is public. |
276 | 4 | keyStrings | Offset to the string pool of entry names. |
280 | 4 | lastPublicKey | Last index into keyStrings that is public. |
284 | 4 | typeIdOffset | Added to type indexes to make type IDs (normally 0). |
The two string pools follow, then for each type a type spec chunk and one type chunk per configuration, and optionally library, overlayable and staged alias chunks.
Type spec (0x0202)
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0202, headerSize 16. |
8 | 1 | id | Type ID (1 or more). |
9 | 1 | res0 | 0. |
10 | 2 | typesCount | Number of type chunks for this type. |
12 | 4 | entryCount | Number of entries. |
16 | 4 × entryCount | flags | Per entry: the configuration axes on which its values differ (bits matching the configuration change flags), plus 0x40000000 SPEC_PUBLIC (public) and 0x20000000 SPEC_STAGED_API (staged; implies public). |
Type (0x0201)
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 8 | header | Type 0x0201. |
8 | 1 | id | Type ID. |
9 | 1 | flags | 0x01 FLAG_SPARSE: offsets are given only for entries that are present (the sparse entry layout is not detailed here). 0x02 FLAG_OFFSET16: offsets are uint16 values times 4, 0xFFFF for none. |
10 | 2 | reserved | 0. |
12 | 4 | entryCount | Number of entry offsets. |
16 | 4 | entriesStart | Offset from the chunk start to the entry data. |
20 | varies | config | The configuration these values are for. |
| headerSize | 4 × entryCount | offsets | Offset of each entry from entriesStart, or 0xFFFFFFFF (NO_ENTRY) when the entry has no value in this configuration. |
Entries
A simple entry (ResTable_entry) is 8 bytes followed by a Res_value:
| Offset | Size | Field | Meaning |
|---|---|---|---|
0 | 2 | size | Size of this header (8, or 16 for a map entry). |
2 | 2 | flags | 0x0001 FLAG_COMPLEX: a map entry (style, array, plural, attribute). 0x0002 FLAG_PUBLIC. 0x0004 FLAG_WEAK: may be overridden by a strong value of the same name. 0x0008 FLAG_COMPACT: compact form, below. |
4 | 4 | key | Index into the package’s keyStrings: the entry name. |
A compact entry (FLAG_COMPACT) is 8 bytes with no Res_value after it: a uint16 key index, the uint16 flags with the value’s dataType in their high 8 bits, and the uint32 data.
A map entry (FLAG_COMPLEX, ResTable_map_entry) adds
parent (uint32 resource ID of the parent style, or 0) and
count (uint32), followed by count name–value pairs
(ResTable_map, 12 bytes each: a uint32 name, which is an attribute
resource ID or one of the codes below, and a Res_value).
| Name | Constant | Meaning |
|---|---|---|
0x01000000 | ATTR_TYPE | In an attribute definition: the allowed value types, a bit set (below). |
0x01000001 | ATTR_MIN | Minimum integer value. |
0x01000002 | ATTR_MAX | Maximum integer value. |
0x01000003 | ATTR_L10N | Localisation: 0 not required, 1 suggested. |
0x01000004 | ATTR_OTHER | Plural quantity “other”. |
0x01000005 | ATTR_ZERO | Plural “zero”. |
0x01000006 | ATTR_ONE | Plural “one”. |
0x01000007 | ATTR_TWO | Plural “two”. |
0x01000008 | ATTR_FEW | Plural “few”. |
0x01000009 | ATTR_MANY | Plural “many”. |
ATTR_TYPE bits: 0x0001 reference, 0x0002 string,
0x0004 integer, 0x0008 boolean, 0x0010 colour,
0x0020 float, 0x0040 dimension, 0x0080 fraction,
0xFFFF any, 0x10000 enum, 0x20000 flags. For enum
and flags attributes, the other pairs map each named value’s ID to its integer.
Configuration (ResTable_config)
Starts with its own size, so older, shorter forms can be read. A field of 0 means “any”.
| Offset | Size | Field | Values |
|---|---|---|---|
0 | 4 | size | Size of this structure. |
4 | 2 | mcc | Mobile country code. |
6 | 2 | mnc | Mobile network code. |
8 | 2 | language | Language code, two ASCII letters. |
10 | 2 | country | Region code, two ASCII letters. |
12 | 1 | orientation | 1 port, 2 land, 3 square. |
13 | 1 | touchscreen | 1 notouch, 2 stylus, 3 finger. |
14 | 2 | density | Dots per inch: 120 ldpi, 160 mdpi, 213 tvdpi, 240 hdpi, 320 xhdpi, 480 xxhdpi, 640 xxxhdpi, 0xFFFE anydpi, 0xFFFF nodpi. |
16 | 1 | keyboard | 1 nokeys, 2 qwerty, 3 12key. |
17 | 1 | navigation | 1 nonav, 2 dpad, 3 trackball, 4 wheel. |
18 | 1 | inputFlags | Bits 0–1 keys hidden (1 keysexposed, 2 keyshidden, 3 keyssoft); bits 2–3 navigation hidden (1 navexposed, 2 navhidden). |
19 | 1 | grammaticalInflection | Bits 0–1: 1 neuter, 2 feminine, 3 masculine. |
20 | 2 | screenWidth | Pixels. |
22 | 2 | screenHeight | Pixels. |
24 | 2 | sdkVersion | Minimum API level (-v21). |
26 | 2 | minorVersion | 0. |
28 | 1 | screenLayout | Bits 0–3 size (1 small, 2 normal, 3 large, 4 xlarge); bits 4–5 long (1 notlong, 2 long); bits 6–7 layout direction (1 ldltr, 2 ldrtl). |
29 | 1 | uiMode | Bits 0–3 type (1 normal, 2 desk, 3 car, 4 television, 5 appliance, 6 watch, 7 vrheadset); bits 4–5 night (1 notnight, 2 night). |
30 | 2 | smallestScreenWidthDp | -sw600dp and so on. |
32 | 2 | screenWidthDp | -w720dp. |
34 | 2 | screenHeightDp | -h720dp. |
36 | 4 | localeScript | ISO 15924 script, such as Latn. |
40 | 8 | localeVariant | Locale variant. |
48 | 1 | screenLayout2 | Bits 0–1 round screen (1 notround, 2 round). |
49 | 1 | colorMode | Bits 0–1 wide colour gamut (1 no, 2 yes); bits 2–3 HDR (1 lowdr, 2 highdr). |
50 | 2 | screenConfigPad2 | Padding. |
52 | 1 | localeScriptWasComputed | Whether the script was filled in by the tools rather than given. |
53 | 8 | localeNumberingSystem | Unicode numbering system, such as latn. |
Library (0x0203)
Header (headerSize 12) with count (uint32), then count
entries of 260 bytes: packageId (uint32) and packageName
(128 UTF-16 units). It maps the package IDs of the shared libraries the app uses to
their names, so dynamic references can be resolved.
Overlayable (0x0204) and policy (0x0205)
The overlayable chunk’s header (headerSize 1032) holds name and
actor, 256 UTF-16 units each. Policy chunks inside it (headerSize 16) hold
policy_flags and entry_count (uint32 each), then that many
resource IDs that overlays meeting the policy may replace.
| Flag | Policy | Overlays allowed |
|---|---|---|
0x00000001 | PUBLIC | Any overlay |
0x00000002 | SYSTEM_PARTITION | On the system partition |
0x00000004 | VENDOR_PARTITION | On the vendor partition |
0x00000008 | PRODUCT_PARTITION | On the product partition |
0x00000010 | SIGNATURE | Signed with the same key as the target |
0x00000020 | ODM_PARTITION | On the ODM partition |
0x00000040 | OEM_PARTITION | On the OEM partition |
0x00000080 | ACTOR_SIGNATURE | Signed with the same key as the actor |
0x00000100 | CONFIG_SIGNATURE | Signed with the key named in the device configuration |
Staged alias (0x0206)
Header (headerSize 12) with count, then count pairs of
uint32 stagedResId and finalizedResId: framework resources
used before an API level was final, mapped to their final IDs.
Sources
AOSP frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h
(every structure, chunk type, data type, complex value constant, flag and policy value
on this page) and the NDK reference for android/configuration.h (the
numeric ACONFIGURATION_* values used in the configuration table).
Byte offsets are worked out from the structure definitions.