Node attribute紧跟Node header,我们先看看Android源码中的结构:
struct ResXMLTree_attrExt
{
// String of the full namespace of this element.
struct ResStringPool_ref ns;
// String name of this node if it is an ELEMENT; the raw
// character data if this is a CDATA node.
struct ResStringPool_ref name;
// Byte offset from the start of this structure where the attributes start.
uint16_t attributeStart;
// Size of the ResXMLTree_attribute structures that follow.
uint16_t attributeSize;
// Number of attributes associated with an ELEMENT. These are
// available as an array of ResXMLTree_attribute structures
// immediately following this node.
uint16_t attributeCount;
// Index (1-based) of the "id" attribute. 0 if none.
uint16_t idIndex;
// Index (1-based) of the "class" attribute. 0 if none.
uint16_t classIndex;
// Index (1-based) of the "style" attribute. 0 if none.
uint16_t styleIndex;
};
然后再看看AXMLPrinter中的代码:
if (chunkType==CHUNK_XML_START_TAG) {
m_namespaceUri=m_reader.readInt();
m_name=m_reader.readInt();
/*flags?*/m_reader.skipInt();
int attributeCount=m_reader.readInt();
m_idAttribute=(attributeCount>>>16)-1;
attributeCount&=0xFFFF;
m_classAttribute=m_reader.readInt();
m_styleAttribute=(m_classAttribute>>>16)-1;
m_classAttribute=(m_classAttribute & 0xFFFF)-1;
m_attributes=m_reader.readIntArray(attributeCount*ATTRIBUTE_LENGHT);
for (int i=ATTRIBUTE_IX_VALUE_TYPE;i<m_attributes.length;) {
m_attributes[i]=(m_attributes[i]>>>24);
i+=ATTRIBUTE_LENGHT;
}
m_namespaces.increaseDepth();
m_event=START_TAG;
break;
}
我们可以发现,二者是基本吻合的。不过AXMLPrinter有的东西似乎还没完全吃透,skip掉的flag实际上是attributeStart和attributeSize。
最后再看一个实际的AXML文件(图中的attributeStart和attributeSize均为0x14)
注:各个字段的size加起来恰好等于Node Header中的size:16+20+0x14=56=0x38