Android打包-基礎知識-Android程式設計師必回
從開始著手公司app安卓原生版本的開發,到如今2.3釋出,已經過了快半年的時間,在這半年的時間裡,已經逐漸掌握了Android 打包的一些基礎知識。今天在這裡小小梳理一下,順便總結下安卓打包中需要注意的問題和一些有效的經驗。
打包過程介紹
首先,需要注意的是不管是打什麼包,或者用什麼工具打包,其背後都是執行的Android提供的構建系統。所以我們先從每個過程介紹一下Android Build系統是如何一步一步將 java檔案、資原始檔、第三方庫等打包成APK的。
Paste_Image.png
資原始檔的預編譯
打包過程的第一步,便是資原始檔的預編譯,資原始檔包括所有位於res/目錄下的所有檔案以及所有的AndroidManifest檔案,在這一步中Android使用aapt
id資源
menu資源
我們可以使用appt命令輸出打包好的apk中所有的資原始檔列表
appt dump resources <path-to-apk>
AIDL檔案編譯
AIDL 全稱Android Interface definition language。在Android如果涉及到多程序比如遠端service的時候就需要去定義aidl檔案,用來統一描述進行間通訊的介面。
interface IMyAidlInterface { /** * Demonstrates some basic types that you can use as parameters * and return values in AIDL. */ void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString); }
Android打包時會將aidl檔案轉化為一個同名的java介面,如下圖所以,可以在/build/generated/source/aidl下看到。
AIDL打包
Java檔案的編譯
這一步是標準的java檔案編譯的過程,編譯的輸入既包括我們手動編寫的程式碼也包括前兩步中生成java檔案。編譯的輸出為.class檔案。
生成.dex檔案
第四步將上一步生成的class檔案,以及引用的第三方庫中的class檔案一起轉化為Dalvik位元組碼。
雖然Android使用Java語言程式設計。但是Android並不使用標準的Java虛擬機器進行java code。Android有自己的虛擬機器 Dalvik以及5.0以上的ART。 可以大致瞭解一下Dalvik虛擬機器和傳統虛擬機器的區別:
- Dalvik虛擬機器佔用記憶體更少
- JVM是基於Stack的(Stack based),DVM是基於Register的(Register based). 跟進一步說,JVM將區域性變數存在stack中,而DVM將變數儲存在register中。因此標準java虛擬機器需要更多的指令集,而DVM的指令集更少,另一方面DVM需要用暫存器編碼指令的source 和 destination ,因此Dalvik的一條指令更長。
- 在JVM執行時,會根據需要去load每個class檔案。而Dalvik中所有的class都在一個dex檔案中。
基於第三條區別,我們在前第三步中生成的所有class檔案以及第三庫中引用的class檔案都需要一起整合為一個dex檔案。
JVM_vs_DVM.jpg
不過這裡有一個潛在的危險,由於dex設計上的原因,單個dex內最多能引用的方法數上限為65536,這個數字對於當今很多APP來說都已經不夠用了,不行的是,我們專案中就碰到了。不過Google也早早就放出瞭解決方案。這裡就不詳細討論了,有興趣瞭解可以戳這裡。
資原始檔打包
第一步資原始檔已經使用aapt進行了預編譯,是為了 讓所有引用了資源的java檔案正常編譯,這裡在打包之前,Android build system需要將所有的資原始檔進行打包。這裡依然是使用第一步中用到的aapt工具。打包後會生成一個resources-debug.ap_檔案,這個檔案中包含了圖片,layout,menu,anim, AndroidManifest,其中圖片都經過了優化,xml檔案被編譯成二進位制格式。string被編譯成單獨的resources.arsc檔案。
打包APK
第五步就是打包APK了,這一步的工作就是將dex檔案,資原始檔(編譯的和未編譯的)打包在一塊,生成apk。
簽名
第五步生成的apk檔案,必須經過簽名才能安裝在裝置上。簽名前,我們必須生成自己的keystore
$ keytool -genkey -v -keystore my-release-key.keystore-alias alias_name -keyalg RSA -keysize 2048 -validity 10000
使用keytool,生成一個keystore,這個keystore包含一個有效期10000天的key。
要對apk進行簽名,需要用到java提供的簽名工具
$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1-keystore my-release-key.keystore my_application.apk alias_name
如果需要驗證某個apk是否簽名過,可以使用
jarsigner -verify -verbose -certs my_application.apk
對齊
打包apk的最後一步是一個對齊工作。這一步的工具簡而言之就是使apk內所有未壓縮的所有檔案相對於apk的其實位置都是4位元組對齊的。這樣,這些檔案既可以直接使用mmap對映訪問。這樣做的目的是為了減少app在執行時所佔用的記憶體。
zipalign -c -v 4 application.apk
作者:呆萌狗和求疵喵
連結:https://www.jianshu.com/p/45da3b9b0ac8
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。