map_off字段 这个字段主要保存map开始位置,就是从文件头开始到map出现的数据长度,通过这个索引就可以找到map数据。那么map保存些什么数据呢?有什么作用呢?下面就来解决这两个问题,首先来分析map的数据结构:
名称 |
大小 |
说明 |
size |
4字节 |
map里项的个数 |
list |
变长 |
每一项定义为12字节,项的个数由上面项大小决定。 |
每一个map项的结构定义如下:
/*
*Direct-mapped "map_item".
*/
typedefstruct DexMapItem {
u2 type; /* type code (seekDexType* above) */
u2 unused;
u4 size; /* count of items ofthe indicated type */
u4 offset; /* file offset tothe start of data */
}DexMapItem;
map数据排列结构定义如下:
/*
*Direct-mapped "map_list".
*/
typedefstruct DexMapList {
u4 size; /* #of entries inlist */
DexMapItem list[1]; /* entries */
}DexMapList;
DexMapItem结构定义每一项的数据意义:类型、类型个数、类型开始位置。其中的类型定义如下:
/*map item type codes */
enum{
kDexTypeHeaderItem = 0x0000,
kDexTypeStringIdItem = 0x0001,
kDexTypeTypeIdItem = 0x0002,
kDexTypeProtoIdItem = 0x0003,
kDexTypeFieldIdItem = 0x0004,
kDexTypeMethodIdItem = 0x0005,
kDexTypeClassDefItem = 0x0006,
kDexTypeMapList = 0x1000,
kDexTypeTypeList = 0x1001,
kDexTypeAnnotationSetRefList = 0x1002,
kDexTypeAnnotationSetItem = 0x1003,
kDexTypeClassDataItem = 0x2000,
kDexTypeCodeItem = 0x2001,
kDexTypeStringDataItem = 0x2002,
kDexTypeDebugInfoItem = 0x2003,
kDexTypeAnnotationItem = 0x2004,
kDexTypeEncodedArrayItem = 0x2005,
kDexTypeAnnotationsDirectoryItem = 0x2006,
};
从上面的类型可知,它已经包括在dex文件里出现的所有类型。细心的读者也许发现这里的类型与文件头里定义的类型有很多是一样的,没错,这里的类型其实就是文件头里定义的类型。因为这个map的数据,就是头里类型的重复,完全是为了检验作用而存在的。当Android系统加载dex文件时,如果比较文件头类型个数与map里类型不一致时,就会停止使用这个dex文件。