一、简述
AXML即Android Binary XML,是Android应用程序APK包中保存xml文件数据的一种方式,可以减小xml文件的大小。本文章与我的另一篇文章手把手教你解析Resources.arsc是相关联的,resources.arsc文件是apk的资源索引文件,而xml文件是apk的资源文件,resources.arsc保存了xml中需要用到的资源的索引,它们之间有非常强的依赖关系,apk在执行的时候缺一不可。另外大家在用AXMLPrinter去解码AXML文件时会看见输出中有很多属性的值都是一串数字,很难明白是什么意思,实际上这串数字就是资源的索引id值,需要用这个id去resources.arsc中查找才能得到具体的字符串,知道这个属性的值是@string/XXXX或者@drawable/XXXX等等。
在上面的文章中我介绍了Resources.arsc文件的解析方式,本文我来介绍怎样来解析AXML文件。
二、AXML文件格式
AXML文件的格式与resources.arsc的文件格式有点类似,如果你清楚resources.arsc文件格式的话,那学习AXML文件格式就更方便了。AXML文件格式所需要的数据结构和resources.arsc的数据结构在同一个文件中定义,都在系统源码的/frameworks/base/include/androidfw/ResourceType.h中,也用到了chunk的概念,文件是以chunk为单位划分的,每个chunk都有chunk header和chunk body。chunk的类型在ResourceType.h文件中有定义:
struct ResChunk_header
{
enum
{
RES_NULL_TYPE = 0x0000,
RES_STRING_POOL_TYPE = 0x0001,
RES_TABLE_TYPE = 0x0002,
// Chunk types in RES_XML_TYPE
RES_XML_TYPE = 0x0003,
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,
// Chunk types in RES_TABLE_TYPE
RES_TABLE_PACKAGE_TYPE = 0x0200,
RES_TABLE_TYPE_TYPE = 0x0201,
RES_TABLE_TYPE_SPEC_TYPE = 0x0202
};
//当前这个chunk的类型
uint16_t type;
//当前这个chunk的头部大小
uint16_t headerSize;
//当前这个chunk的大小
uint32_t size;
};
具体格式如下图:
图1
可以看到和resources.arsc一样,在文件的头部后面紧接着是一个string pool,存放着文件中需要用到的字符串。后面是一个XMLResourceMap,它的作用是:This contains a uint32_t array mapping strings in the string pool back to resource identifiers. It is optional.由于我对应用中使用资源文件不太熟悉,所以没看明白,以后明白了再更新,但这个chunk是optional的。
再往后是一个Namespace,个人理解和C里面的namespace一个意思吧,类型是RES_XML_START_NAMESPACE_TYPE,Namespace里面是一个个的Element,类型是RES_XML_START_ELEMENT_TYPE,实际上对应着xml中的一个个tag,每个Element里面还有att