apk 是Android Package的簡寫, 在平時的開發(fā)過程中,通過點擊 Run app 按鈕 或者 在命令行中輸入
創(chuàng)新互聯(lián)建站于2013年創(chuàng)立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務公司,擁有項目網(wǎng)站設計制作、網(wǎng)站設計網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元張灣做網(wǎng)站,已為上家服務,為張灣各地企業(yè)和個人服務,聯(lián)系電話:13518219792
這樣Android Studio就會啟動構(gòu)建流程,最終輸出一個我們想要的APK。
直達官網(wǎng)介紹
對于小白來說,上面一張圖已經(jīng)可以解釋apk的構(gòu)建過程了,不過對于Andoid開發(fā)者而言還需要了解一些更詳細的構(gòu)建過程。
詳細的對應步驟 和 使用工具如下:
資源文件(res文件夾下的文件)通過 AAPT(Android Asset Packaging Tool)打包生成R.java類(資源索引表)、.arsc資源文件 和res文件。
resources.arsc 是一個App的資源索引表,通過R.java 文件 和 resources.arsc 可以定位到資源的內(nèi)存地址,resources.arsc文件的作用是通過一樣的ID,根據(jù)不同的配置索引到最佳的資源顯示在UI中。
AIDL (Android Interface Definition Language), 是Android接口定義語言,是Android提供的IPC (Inter Process Communication,進程間通信)的一種獨特實現(xiàn)。
如果有aidl文件,這個階段會生成對應的Java接口文件。
R.java文件、工程源碼文件、aidl.java文件, 在這一步通過javac生成.class文件。
源碼.class文件和第三方jar或者library通過dx工具打包成dex文件
Android系統(tǒng)的Dalvik虛擬機的可執(zhí)行文件為DEX格式,所以這里會將上一步中生成的.class文件 和 引用的第三方jar等過程中的.class 一起通過dx工具打包成dex文件
apkbuilder工具會將所有沒有編譯的資源、.arsc資源、.dex文件打包到一個完成apk文件中
tips:
apksigner工具會對未簽名的apk驗證簽名。得到一個簽名后的apk(signed.apk)
apksigner 是google 退出的V2簽名方式
Jarsigner 是之前一直使用的V1簽名方式
可以通過在命令行中輸入apksigner --help來獲取詳情信息,如果沒有特殊需求,使用下面命令即可完成簽名
release mode 下使用 aipalign進行align,即對簽名后的apk進行對齊處理
所謂對齊,主要過程是將APK包中所有的資源文件距離文件起始偏移為4字節(jié)整數(shù)倍,這樣通過內(nèi)存映射訪問apk文件時的速度會更快。對齊的作用主要是為了減少運行時內(nèi)存的使用。
zipalign是一個android平臺上整理APK文件的工具,它對apk中未壓縮的數(shù)據(jù)進行4字節(jié)對齊,對齊后就可以使用mmap函數(shù)讀取文件,可以像讀取內(nèi)存一樣對普通文件進行操作。如果沒有4字節(jié)對齊,就必須顯式的讀取,這樣比較緩慢并且會耗費額外的內(nèi)存。
參考文章:
Android-Studio配置構(gòu)建
淺談Android打包流程
apk打包流程
END!
如下圖所示,在編譯apk的時候,我需要把libs/armeabi-v7a下的so庫一起打包到apk里面。
需要在build.gradle中添加如下內(nèi)容:
ndk {
abiFilters "armeabi-v7a"
}
sourceSets.main.jniLibs.srcDirs = ['libs']
===============================================================
深圳上班,
生活簡簡單單,
14年開始從事Android Camera相關(guān)軟件開發(fā)工作,
做過車載、手機、執(zhí)法記錄儀......
公眾號記錄生活和工作的點滴,
關(guān)注“小馳筆記”,期待和你相遇~
第一:使用apktool直接反編譯apk
第二:apk中包含的內(nèi)容
第三:進入到hellodemo\smali\com\example\hello,打開MainActivity.smali。找到:
const-string v1, "\u4f60\u597d",
修改為:
const-string v1, "hello",
第四:然后在命令行輸入:apktool b hellodemo hellodemo1.apk。這回重新打包成hellodemo1.apk。
第五:然后給新生成的apk進行簽名。把這個apk拷貝到autosign的目錄下面,然后切換過去,在命令行輸入:java -jar signapk.jar testkey.x509.pem testkey.pk8 hellodemo1.apk hellodemo.apk。
第六:把生成的hellodemo.apk安裝到手機,可以看到主界面上已經(jīng)顯示的是hello,而不再是你好。說明反編譯重新打包成功!
下圖的是官網(wǎng)對于Android編譯打包流程的介紹。
官方的介紹非?;\統(tǒng),簡而言之,其大致流程就是:
編譯--DEX--打包--簽名和對齊
(好像什么都沒Get到,有一種意猶未盡的感覺……)
來一張外國大神的圖片(注:這張圖少了簽名的步驟)
用文字解釋一下上圖的流程:
首先,我們整理一下編譯的輸入部分是什么(圖中黃色部分):
接下來的步驟:
好了,編譯打包的詳細流程說完了,接下來我們看看是否能回答開篇的那些問題。
答:aapt工具對于每個資源文件生成了唯一的ID,這些ID保存在R.java文件中。如下是R.java文件的內(nèi)容:
資源ID是一個4字節(jié)的無符號整數(shù),在R.java文件中用16進制表示。其中,最高的1字節(jié)表示Package ID,次高1個字節(jié)表示Type ID,最低2字節(jié)表示Entry ID。
只有一個ID如何能引用到實際資源呢?實際上aapt工具還生成了一個文件resources.arsc,相當于一個資源索引表,或者你理解成一個map也行,map的key是資源ID,value是資源在apk文件中的路徑。resources.arsc里面還有其他信息,這個就不多說了。
通過R.java文件和resources.arsc配合,就能引用到實際的資源文件。
答:第7步已經(jīng)闡述了對齊所做的工作,為什么要進行對齊,這是為了加快資源的訪問速度。如果每個資源的開始位置都是上一個資源之后的 4*n字節(jié),那么訪問下一個資源就不用遍歷,直接跳到4*n字節(jié)處判斷是不是一個新的資源即可。
如果舉例子,那么對齊有點類似于資源數(shù)組化,數(shù)組的訪問速度當然比鏈表快。
答:xml里面都是各種字符,不利于快速遍歷。編譯成二進制文件,用數(shù)字替換各種符號,一方面能快速訪問,另一方面也能減少大小。