記筆記,寫總結的意義就在於,它們是你掌控這些知識的證明,即使有一天你記不住它們了,但是一翻筆記,知識又能很快回到你腦子裏。
一、庫文件
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文件結構內容較多,放到下一篇文章中單獨學習。