深入詳解Apk編譯打包流程
前言
身為一個(gè)Android開發(fā),一定要了解apk編譯打包流程;
那么今天我們就來學(xué)習(xí)下;
apk的編譯流程
1、apk文件
- apk是Android Package的縮寫;
- 解壓apk文件后包含AndroidManifest.xml、assets目錄、classes.dex(還可能有 classes2.dex,classes3.dex...classesN.dex)、lib目錄、META-INF目錄、res目錄和resources.arsc;
- classes.dex 是.dex文件;
- resources.arsc是resources resources文件;
- AndroidManifest.xml是AndroidManifest.xml文件;
- res是uncompiled resources;
- META-INF是簽名文件夾;
2、打包流程
打包中需要的工具
- aapt:Android資源打包工具,${ANDROID_SDK_HOME}/platform-tools/appt
- aidl:Android接口描述語言轉(zhuǎn)化為.java文件的工具,${ANDROID_SDK_HOME}/platform-tools/aidl
- javac:Java Compiler,${JDK_HOME}/javac或/usr/bin/javac
- dex:轉(zhuǎn)化.class文件為Davik VM能識(shí)別的.dex文件,${ANDROID_SDK_HOME}/platform-tools/dx
- apkbuilder:生成apk包,${ANDROID_SDK_HOME}/tools/opkbuilder
- jarsigner:.jar文件的簽名工具,${JDK_HOME}/jarsigner或/usr/bin/jarsigner
- zipalign:字節(jié)碼對(duì)齊工具,${ANDROID_SDK_HOME}/tools/zipalign
2.1打包資源文件,生成R.java文件
使用aapt來打包res資源文件,生成R.java、resources.arsc和res文件(二進(jìn)制 & 非二進(jìn)制如res/raw和pic保持原樣);
res目錄
- animator:這類資源以XML文件保存在res/animator目錄下,用來描述屬性動(dòng)畫;
- anim:這類資源以XML文件保存在res/anim目錄下,用來描述補(bǔ)間動(dòng)畫;
- color:這類資源以XML文件保存在res/color目錄下,用描述對(duì)象顏色狀態(tài)選擇子;
- drawable:這類資源以XML或者Bitmap文件保存在res/drawable目錄下,用來描述可繪制對(duì)象。例如,我們可以在里面放置一些圖片(.png, .9.png, .jpg, .gif),來作為程序界面視圖的背景圖;
- layout:這類資源以XML文件保存在res/layout目錄下,用來描述應(yīng)用程序界面布局;
- menu:這類資源以XML文件保存在res/menu目錄下,用來描述應(yīng)用程序菜單;
- raw:這類資源以任意格式的文件保存在res/raw目錄下,它們和assets類資源一樣,都是原裝不動(dòng)地打包在apk文件中的,不過它們會(huì)被賦予資源ID,這樣我們就可以在程序中通過ID來訪問它們。例如,假設(shè)在res/raw目錄下有一個(gè)名稱為filename的文件,并且它在編譯的過程,被賦予的資源ID為R.raw.filename,那么就可以使用以下代碼來訪問它:
- Resources res = getResources();
- InputStream is = res .openRawResource(R.raw.filename);
- values:這類資源以XML文件保存在res/values目錄下,用來描述一些簡(jiǎn)單值,例如,數(shù)組、顏色、尺寸、字符串和樣式值等,一般來說,這六種不同的值分別保存在名稱為arrays.xml、colors.xml、dimens.xml、strings.xml和styles.xml文件中;
- xml:這類資源以XML文件保存在res/xml目錄下,一般就是用來描述應(yīng)用程序的配置信息;
resources.arsc文件
- resources.arsc這個(gè)文件記錄了所有的應(yīng)用程序資源目錄的信息,包括每一個(gè)資源名稱、類型、值、ID以及所配置的維度信息;
- 我們可以將這個(gè)resources.arsc文件想象成是一個(gè)資源索引表,這個(gè)資源索引表在給定資源ID和設(shè)備配置信息的情況下,能夠在應(yīng)用程序的資源目錄中快速地找到最匹配的資源;
R.java文件
- R.java文件,里面擁有很多個(gè)靜態(tài)內(nèi)部類,比如layout,string等;
- 每當(dāng)有這種資源添加時(shí),就在R.java文件中添加一條靜態(tài)內(nèi)部類里的靜態(tài)常量類成員,且所有成員都是int類型;
2.2處理AIDL文件,生成對(duì)應(yīng)的.java文件
- AIDL (Android Interface Definition Language), Android接口定義語言,Android提供的IPC (Inter Process Communication,進(jìn)程間通信)的一種獨(dú)特實(shí)現(xiàn);
- 這個(gè)階段處理.aidl文件,生成對(duì)應(yīng)的Java接口文件;
2.3編譯Java文件,生成對(duì)應(yīng)的.class文件
- 編譯工程源碼,生成相應(yīng)的class文件。處理文件包括src、R.java、AIDL生成的 java 文件,庫(kù)jar文件;
- 調(diào)用了javac編譯工程的src目錄下所有的java源文件,生成的class文件位于工程的bin\classess目錄下;
2.4把.class文件轉(zhuǎn)化成Davik VM支持的.dex文件
- 轉(zhuǎn)換所有的class文件,生成classes.dex文件。處理文件就是上一步生成的 .class 文件;
- 使用dx工具將java字節(jié)碼轉(zhuǎn)換為dalvik字節(jié)碼、壓縮常量池、消除冗余信息等;
- 通過dex命令,將.class文件和第三方庫(kù)中的.class文件處理生成classes.dex;
2.5打包生成未簽名的.apk文件
- 將classes.dex、resources.arsc、res文件夾(res/raw資源被原裝不動(dòng)地打包進(jìn)APK之外,其它的資源都會(huì)被編譯或者處理)、Other Resources(assets文件夾)、AndroidManifest.xml打包成apk文件;
注意:
res/raw和assets的相同點(diǎn):
兩者目錄下的文件在打包后會(huì)原封不動(dòng)的保存在apk包中,不會(huì)被編譯成二進(jìn)制;
res/raw和assets的不同點(diǎn):
- res/raw中的文件會(huì)被映射到R.java文件中,訪問的時(shí)候直接使用資源ID即R.id.filename;assets文件夾下的文件不會(huì)被映射到R.java中,訪問的時(shí)候需要AssetManager類;
- res/raw不可以有目錄結(jié)構(gòu),而assets則可以有目錄結(jié)構(gòu),也就是assets目錄下可以再建立文件夾;
2.6對(duì)未簽名.apk文件進(jìn)行簽名
- android的應(yīng)用程序需要簽名才能在android設(shè)備上安裝,簽名apk文件有兩種情況:
- 在調(diào)試應(yīng)用程序時(shí),也就是我們通常稱為的debug模式的簽名,平時(shí)開發(fā)的時(shí)候,在編譯調(diào)試程序時(shí)會(huì)自己使用一個(gè)debug.keystore對(duì)apk進(jìn)行簽名;
- 正式發(fā)布時(shí)對(duì)應(yīng)用程序打包進(jìn)行簽名,這種情況下需要提供一個(gè)符合android開發(fā)文檔中要求的簽名文件。這種簽名也是分兩種:JDK中提供的jarsigner工具簽名 、android源碼中提供的signapk工具;
2.7對(duì)簽名后的.apk文件進(jìn)行對(duì)齊處理
- release mode 下使用 aipalign進(jìn)行align,即對(duì)簽名后的apk進(jìn)行對(duì)齊處理;
- Zipalign是一個(gè)android平臺(tái)上整理APK文件的工具,它對(duì)apk中未壓縮的數(shù)據(jù)進(jìn)行4字節(jié)對(duì)齊,對(duì)齊后就可以使用mmap函數(shù)讀取文件,可以像讀取內(nèi)存一樣對(duì)普通文件進(jìn)行操作。如果沒有4字節(jié)對(duì)齊,就必須顯式的讀取,這樣比較緩慢并且會(huì)耗費(fèi)額外的內(nèi)存;
- 在 Android SDK 中包含一個(gè)名為 “zipalign” 的工具,它能夠?qū)Υ虬蟮?app 進(jìn)行優(yōu)化。其位于 SDK 的 build-tools 目錄下;
總結(jié)
人生很有意思,就像升級(jí)打怪,打了一怪又一怪,雖然過程有辛苦有困難,有失敗的危險(xiǎn),也有后退的風(fēng)險(xiǎn),但是打一怪很有感覺;加油打工人!!!