Every Android application defines a set of Resources.
These Resources are stored in a Resource Table, or in some cases, for example, layouts, as Android specific Binary XML, which is referenced from the Resource Table.
An application’s Resource Table is stored persistently in the application’s .apk file in the resources.arsc file. Binary XML data is also stored in files in the .apk.
The Resource Table and associated Binary XML data is represented both at runtime and when stored in files by Chunks.
As a consequence an application’s Resources can be loaded by simply mapping the files that contain them into memory.
2.0 Chunks
A Chunk is just a piece of memory split into two parts, a header and a body. The exact structure of the header and the body of a given Chunk is determined by its type.
2.1 Chunk Types
The possible Chunk types are defined by the following C++ enum (see frameworks/base/include/ResourceTypes.h lines 179-201)
enum {
RES_NULL_TYPE = 0x0000,
RES_STRING_POOL_TYPE = 0x0001,
RES_TABLE_TYPE = 0x0002,
RES_XML_TYPE = 0x0003,
// Chunk types in RES_XML_TYPE
RES_XML_FIRST_CHUNK_TYPE = 0x0100,
RES_XML_START_NAMESPACE_TYPE= 0x0100,
RES_XML_END_NAMESPACE_TYPE = 0x0101,
RES_XML_START_ELEMENT_TYPE = 0x0102,
RES_XML_END_ELEMENT_TYPE = 0x0103,
RES_XML_CDATA_TYPE = 0x0104,
RES_XML_LAST_CHUNK_TYPE = 0x017f,
// This contains a uint32_t array mapping strings in the string
// pool back to resource identifiers. It is optional.
RES_XML_RESOURCE_MAP_TYPE = 0x0180,
All Chunk headers irrespective of the Chunk type have an instance of the C++ struct ResChunk_header (see frameworks/base/include/ResourceTypes.h lines 160-177)
as their first field
struct ResChunk_header
{
// Type identifier for this chunk. The meaning of this value depends
// on the containing chunk.
uint16_t type;
// Size of the chunk header (in bytes). Adding this value to
// the address of the chunk allows you to find its associated data
// (if any).
uint16_t headerSize;
// Total size of this chunk (in bytes). This is the chunkSize plus
// the size of any data associated with the chunk. Adding this value
// to the chunk allows you to completely skip its contents (including
// any child chunks). If this value is the same as chunkSize, there is
// no data associated with the chunk.
uint32_t size;
};
This means that given the address, A, of any Chunk it is always possible to determine
•its type
•where the body of the Chunk starts (A + headerSize)
•where the next Chunk, if any, starts (A + size)
without knowing anything further about the structure of the given Chunk.
2.3 Byte Order
By default the data in Chunks is in little-endian byte order both at runtime and when stored in files.
The bytes in blue are the Table chunk header and those in green, that is, everything else, the Table chunk body.
2.0 The Table Chunk Header
The format of a Table chunk header is defined by the following C++ struct (see frameworks/base/include/ResourceTypes.h lines 755-761)
struct ResTable_header
{
struct ResChunk_header header;
// The number of ResTable_package structures.
uint32_t packageCount;
};
2.1 header
The header field is a struct ResChunk_header instance.
The header.type field is always 0x0002. (RES_TABLE_TYPE)
The header.headerSize field is always 0x000c.
2.2 packageCount
The packageCount field specifies the number of Packages contained in the Table.
2.3 The Example Annotated
This is an annotated version of the Table chunk header from the example.