第一步:打包資源文件,生成R.java文件。
【輸入】Resource文件(就是工程中res中的文件)、Assets文件(相當(dāng)于另外一種資源,這種資源Android系統(tǒng)并不像對res中的文件那樣優(yōu)化它)、AndroidManifest.xml文件(包名就是從這里讀取的,因為生成R.java文件需要包名)、Android基礎(chǔ)類庫(Android.jar文件)
【工具】aapt工具
【輸出】打包好的資源(bin目錄中的resources.ap_文件)、R.java文件(gen目錄中)
打包資源的工具aapt,大部分文本格式的XML資源文件會被編譯成二進(jìn)制格式的XML資源文件,除了assets和res/raw資源被原裝不動地打包進(jìn)APK之外,其它的資源都會被編譯或者處理。 。
生成過程主要是調(diào)用了aapt源碼目錄下的Resource.cpp文件中的buildResource()函數(shù),該函數(shù)首先檢查AndroidManifest.xml的合法性,然后對res目錄下的資源子目錄進(jìn)行處理,處理的函數(shù)為makeFileResource(),處理的內(nèi)容包括資源文件名的合法性檢查,向資源表table添加條目等,處理完后調(diào)用compileResourceFile()函數(shù)編譯res與asserts目錄下的資源并生成resources.arsc文件,compileResourceFile()函數(shù)位于aapt源碼目錄的ResourceTable.cpp文件中,該函數(shù)最后會調(diào)用parseAndAddEntry()函數(shù)生成R.java文件,完成資源編譯后,接下來調(diào)用compileXmlfile()函數(shù)對res目錄的子目錄下的xml文件分別進(jìn)行編譯,這樣處理過的xml文件就簡單的被“加密”了,最后將所有的資源與編譯生成的resorces.arsc文件以及“加密”過的AndroidManifest.xml文件打包壓縮成resources.ap_文件(使用Ant工具命令行編譯則會生成與build.xml中“project name”指定的屬性同名的ap_文件)。
關(guān)于這一步更詳細(xì)的流程可閱讀http://blog.csdn.net/luoshengyang/article/details/8744683
第二步:處理aidl文件,生成相應(yīng)的java文件。
【輸入】源碼文件、aidl文件、framework.aidl文件
【工具】aidl工具
【輸出】對應(yīng)的.java文件
對于沒有使用到aidl的android工程,這一步可以跳過。aidl工具解析接口定義文件并生成相應(yīng)的java代碼供程序調(diào)用。
第三步:編譯工程源代碼,生成下相應(yīng)的class文件。
【輸入】源碼文件(包括R.java和AIDL生成的.java文件)、庫文件(.jar文件)
【工具】javac工具
【輸出】.class文件
這一步調(diào)用了javac編譯工程src目錄下所有的java源文件,生成的class文件位于工程的bin\classes目錄下,上圖假定編譯工程源代碼時程序是基于android SDK開發(fā)的,實際開發(fā)過程中,也有可能會使用android NDK來編譯native代碼,因此,如果可能的話,這一步還需要使用android NDK編譯C/C++代碼,當(dāng)然,編譯C/C++代碼的步驟也可以提前到第一步或第二步。
第四步:轉(zhuǎn)換所有的class文件,生成classes.dex文件。
【輸入】 .class文件(包括Aidl生成.class文件,R生成的.class文件,源文件生成的.class文件),庫文件(.jar文件)
【工具】javac工具
【輸出】.dex文件
前面多次提到,android系統(tǒng)dalvik虛擬機的可執(zhí)行文件為dex格式,程序運行所需的classes.dex文件就是在這一步生成的,使用的工具為dx,dx工具主要的工作是將java字節(jié)碼轉(zhuǎn)換為dalvik字節(jié)碼、壓縮常量池、消除冗余信息等。
第五步:打包生成apk。
【輸入】打包后的資源文件、打包后類文件(.dex文件)、libs文件(包括.so文件,當(dāng)然很多工程都沒有這樣的文件,如果你不使用C/C++開發(fā)的話)
【工具】apkbuilder工具
【輸出】未簽名的.apk文件
打包工具為apkbuilder,apkbuilder為一個腳本文件,實際調(diào)用的是android-sdk\tools\lib\sdklib.jar文件中的com.android.sdklib.build.ApkBuilderMain類。它的代碼實現(xiàn)位于android系統(tǒng)源碼的sdk\sdkmanager\libs\sdklib\src\com\android\sdklib\build\ApkBuilderMain.java文件,代碼構(gòu)建了一個ApkBuilder類,然后以包含resources.arsc的文件為基礎(chǔ)生成apk文件,這個文件一般為ap_結(jié)尾,接著調(diào)用addSourceFolder()函數(shù)添加工程資源,addSourceFolder()會調(diào)用processFileForResource()函數(shù)往apk文件中添加資源,處理的內(nèi)容包括res目錄與asserts目錄中的文件,添加完資源后調(diào)用addResourceFromJar()函數(shù)往apk文件中寫入依賴庫,接著調(diào)用addNativeLibraries()函數(shù)添加工程libs目錄下的Native庫(通過android NDK編譯生成的so或bin文件),最后調(diào)用sealApk()關(guān)閉apk文件。
第六步:對apk文件進(jìn)行簽名。
【輸入】未簽名的.apk文件
【工具】jarsigner
【輸出】簽名的.apk文件
android的應(yīng)用程序需要簽名才能在android設(shè)備上安裝,簽名apk文件有兩種情況:一種是在調(diào)試程序時進(jìn)行簽名,使用eclipse開發(fā)android程序時,在編譯調(diào)試程序時會自己使用一個debug.keystore對apk進(jìn)行簽名;另一種是打包發(fā)布時對程序進(jìn)行簽名,這種情況下需要提供一個符合android開發(fā)文檔中要求的簽名文件。簽名的方法也分兩種:一種是使用jdk中提供的jarsigner工具簽名;另一種是使用android源碼中提供的signapk工具,它的代碼位于android系統(tǒng)源碼build\tools\signapk目錄下。
第七步:對簽名后的apk文件進(jìn)行對齊處理。
【輸入】簽名后的.apk文件
【工具】zipalign工具
【輸出】對齊后的.apk文件
這一步需要使用的工具為zipalign,它位于android-sdk\tools目錄,源碼位于android系統(tǒng)源碼的build\tools\zipalign目錄,它的主要工作是將spk包進(jìn)行對齊處理,使spk包中的所有資源文件距離文件起始偏移為4字節(jié)整數(shù)倍,這樣通過內(nèi)存映射訪問apk文件時速度會更快,驗證apk文件是否對齊過的工作由ZipAlign.cpp文件的verify()函數(shù)完成,處理對齊的工作則由process()函數(shù)完成。