记笔记,写总结的意义就在于,它们是你掌控这些知识的证明,即使有一天你记不住它们了,但是一翻笔记,知识又能很快回到你脑子里。
一、库文件
1.1 jar包
包含一系列class文件的压缩包,class文件是经过编译后的Java代码集合。也叫"jar包"。
问题:
java=>class
java=>dex?
部分对安全性有要求的jar,会对class文件进行签名,签名信息保存在jar包的META-INF目录下。
1.2 aar包
jar包只包含代码,而SDK所需要的图片、视频等资源则只能手动添加。
aar包就包含了所有的代码、图片、等资源。
本质上aar也是zip压缩包,Android Studio开创了aar包的先河。
二、APK
本质:zip压缩包
2.1 APK文件结构
完整的APK包结构:
- AndroidManifest.xml:编译好的AXML二进制格式的文件。
- META-INF目录:用于保存APK的签名信息。
- classes.dex:程序的可执行代码。如果开启了MultiDex,则会有多个DEX文件。
- res目录:程序中使用的资源信息。
- resources.arsc:编译好的二进制格式的资源信息。
- assets目录:如果程序使用Assets系统来存放Raw资源,所有资源都放在这个目录下。
2.2 APK文件的生成流程
aapt打包程序资源,处理AndroidManifest.xml和XML布局文件并生成R.java文件。
使用aidl解析AIDL接口,interface。
调用Java编译器,生成class文件。
dx将所有的class文件和jar包打包生成DEX文件,然后调用apkbulider将上述资源与class文件合并成APK文件。
最后,对APK进行对齐处理和签名。
三、classes.dex
classes.dex中包含APK的可执行代码,它是分析Android软件时最常见的目标。
class文件经过dx处理,变成dex文件。
DEX文件是有多个结构体组合而成的。
由7个部分组成:
dex header为DEX文件头,它指定了DEX文件的一些属性并记录了其他数据结构在DEX文件里的物理偏移;string_ids到class_def部分可以理解为"索引结构区";真实的数据保存在data数据区;link_data为静态链接数据区。
3.1 DEX文件分析
DEX文件由DexFile结构体表示,定义如下:
struct DexFile {
/* directly-mapped "opt" header */
const DexOptHeader* pOptHeader;
/* pointers to directly-mapped structs and arrays in base DEX */
const DexHeader* pHeader;
const DexStringId* pStringIds;
const DexTypeId* pTypeIds;
const DexFieldId* pFieldIds;
const DexMethodId* pMethodIds;
const DexProtoId* pProtoIds;
const DexClassDef* pClassDefs;
const DexLink* pLinkData;
};
分析Android源码的时候我有些懵…我一时理不起来学习线路的思路了…
这时候我翻看了其他大牛的博客,看看他们是怎么理解的,避免入到代码的坑里出不来了。
struct DexHeader {
u1 magic[8]; /* dex的魔数 */
u4 checksum; /* 校验和 */
u1 signature[kSHA1DigestLen]; /* SHA-1哈希值*/
u4 fileSize; /* dex文件的大小 */
u4 headerSize; /* dex文件头的大小 */
u4 endianTag; /* 字节序标记 */
u4 linkSize; /* 链接段大小 */
u4 linkOff; /* 链接段偏移 */
u4 mapOff; /* DexMapList的文件偏移 */
u4 stringIdsSize; /* DexStringId的个数 */
u4 stringIdsOff; /* DexStringId的偏移 */
u4 typeIdsSize; /* DexTypeId的个数 */
u4 typeIdsOff; /* DexTypeId的偏移 */
u4 protoIdsSize; /* DexProtoId的个数 */
u4 protoIdsOff; /* DexStringId的偏移 */
u4 fieldIdsSize; /* DexFieldId的个数 */
u4 fieldIdsOff; /* DexFieldId的偏移 */
u4 methodIdsSize; /* DexMethodId的个数 */
u4 methodIdsOff; /* DexMethodId的偏移 */
u4 classDefsSize; /* DexClassDef的个数 */
u4 classDefsOff; /* DexClassDef的偏移 */
u4 dataSize; /* 数据段的大小 */
u4 dataOff; /* 数据段的偏移 */
};
由于篇幅有限,dex文件结构内容较多,放到下一篇文章中单独学习。