談?wù)劥虬w介紹

????不管你是做移動開發(fā)肴盏、前端開發(fā)還是后端開發(fā),一定會遇到一個概念——打包帽衙,那打包是什么菜皂?為什么要打包?以及如何打包呢厉萝?

打包是什么恍飘,為什么要打包

????在我們?nèi)粘I钪杏心男┏R姷拇虬鼒鼍澳兀柯眯写虬吹妗⒖爝f打包章母、禮品打包、資料文檔打包翩剪,這些打包是指把若干物品在空間上有機的組合在一起乳怎,對外呈現(xiàn)為一個整體的過程打包的目的是為了更方便前弯、安全地儲存蚪缀、運輸、呈現(xiàn)和使用物品恕出。
????在技術(shù)領(lǐng)域依舊如此询枚,打包一般指將程序的源代碼、資源文件和依賴庫等整合成一個整體的過程剃根,打包是為了程序能夠更加方便哩盲、安全的使用(包括存儲、傳輸、復(fù)制廉油、部署惠险、安裝、運行等)抒线。

如何打包

????馬上過年了班巩,X廠要發(fā)放新年大禮包給員工,那制作過程大概是這樣的:確定大禮包物品清單以及包裝盒樣式→確定每個物品擺放位置和順序→按順序?qū)ξ锲愤M行擺放→封包→打上防偽標簽嘶炭,在這個打包過程中抱慌,其實還隱藏著另一個流程,那就是每個步驟所需要的環(huán)境和工具的準備眨猎。在技術(shù)領(lǐng)域抑进,打包過程亦是如此,接下來就Android打包過程具體展開:

Android 打包流程

????打包在Android上也叫APK構(gòu)建睡陪,打包就是把Android工程源碼變?yōu)锳PK的過程寺渗,使用的工具叫Gradle。首先我們得有個認知兰迫,每個APK構(gòu)建的大流程是確定的信殊,只是不同的APP依賴三方庫(物品清單一部分)、簽名(防偽手段)汁果、使用工具集涡拘、打包后存放位置一些自定的地方不同,我們才需要進行對打包控制文件(build.gradle)進行配置据德。我們覺得打包流程不容易理解是因為我們能夠操作的build.gradle等文件都只是配置文件鳄乏,打包的內(nèi)部邏輯和流程是對我們隱藏的。打包跟其他任何工作一樣都是分為三步走:
????確定工作內(nèi)容和范圍→確定工作分工和順序→順序執(zhí)行每個任務(wù)棘利,分別對應(yīng)上述流程汞窗,Android打包也分為三個大的步驟:

  • 初始化(Initialization)
  • 配置(Configuration)
  • 執(zhí)行(Execution)

我們在setting和build.gradle的配置也是在初始化和配置階段生效的。下面我們逐個進行介紹

一 赡译、初始化 Initialization

  1. 從工程源碼根目錄開始查找setting.gradle文件;
  2. 根據(jù)setting.gradle文件中的配置來決定哪些模塊參與構(gòu)建不铆;
  3. 首先為根build.gradle生成一個Project實例蝌焚,接下來為每一個setting.gradle中配置的模塊(對應(yīng)build.gradle)生成一個Project實例,根build.gradle對應(yīng)的Project是其他build.gradle對應(yīng)Project的父Project誓斥;

注意:
????① 因為每個build.gradle 都對應(yīng)一個Project對象只洒,Project對象類似于Android中的 Context,在build.gradle中獲取gradle系統(tǒng)方法都是通過內(nèi)置的project對象或者 getProject() 得到上下文后去獲取劳坑。
????② 這個階段我們配置的task毕谴、回調(diào)都不會被執(zhí)行,可以認為是Android中的類加載到內(nèi)存和實例對象初始化階段。

二涝开、配置 Configuration

1. 對每個build.gradle對應(yīng)的Project進行配置循帐,所謂的配置主要是指 ① 下載并初始化插件 ②配置 Android 的編譯版本、簽名舀武、產(chǎn)品風味等 ③ 下載依賴庫 ④注冊自定義Task 等拄养,其實這四個主要事情也是一個build.gradle中所有的內(nèi)容。project配置和執(zhí)行都是采用廣度優(yōu)先遍歷银舱,那就是父project先執(zhí)行瘪匿,然后是按照Setting.gradle中順序執(zhí)行子project, 這個階段也叫 Project Evaluation
2. 執(zhí)行Project evaluation的回調(diào)寻馏,比如Project.beforeEvalution 棋弥、Project.afterEvalution等;
3. 廣度優(yōu)先順序為每個Project注冊task诚欠,執(zhí)行task create回調(diào)(如果有)顽染,示例如下:

tasks.whenTaskAdded { task ->
    println("hahaha task added call back name= "+task.name)
}

4. 為每一個Task創(chuàng)建一個依賴圖,依賴圖就是來說明運行這個task要先執(zhí)行哪些Task的圖聂薪;
5. 當所有Task的依賴圖構(gòu)建完畢家乘,發(fā)送 task構(gòu)建圖完成通知。如果用戶定義了回調(diào)就可以收到

project.gradle.taskGraph.addTaskExecutionGraphListener(new TaskExecutionGraphListener() {
    @Override
    void graphPopulated(TaskExecutionGraph graph) {
        println("hahaha task TaskExecutionGraph call back")
    }
})

小結(jié):配置就是決定打包的具體內(nèi)容藏澳、使用工具和詳細流程仁锯。我們大部分在build.gradle中自定義的東西都是在配置階段生效和執(zhí)行。

注意:

  • 我們在Android studio執(zhí)行sync的時候其實就是執(zhí)行了初始化+配置翔悠,我們配置了更多的東西比如更多三方庫业崖,更多構(gòu)建變體 這個sync時間就會更長;
  • 執(zhí)行任何Task都要重新執(zhí)行整個項目的初始化和配置階段蓄愁,但是如果之前執(zhí)行過sync或者這兩個步驟双炕,而且所有的buid.gradle都未變化,gradle內(nèi)部會找到之前的緩存并跳過一個個任務(wù)的執(zhí)行撮抓。

三妇斤、執(zhí)行:Execution

????其實前面兩個階段都是讀入決策和準備階段,真正做事都是在這個階段——打包(也叫構(gòu)建丹拯、assemble)站超,根據(jù)不同的構(gòu)建類型和產(chǎn)品風味會有多個打包產(chǎn)物,接下來我們就指對最常見的assembleRelease進行展開乖酬。
????本文前面講所謂打包就是把Android App源碼變?yōu)锳PK的過程死相,Android App工程源碼是什么,結(jié)構(gòu)是怎么樣的咬像,做Android開發(fā)的應(yīng)該都比較清晰算撮,主要有AndroidManifest配置文件生宛、java代碼、kotlin代碼肮柜、XML陷舅、圖片、依賴庫地址素挽、本地庫(jar蔑赘、aar、so)等预明,這里就展開介紹缩赛;而APK其實就是一個包含編譯后的代碼和資源的壓縮文件,我們找到一個APK(改后綴為.zip)解壓得到文件列表如下:

Apk解壓縮.png

重點模塊介紹如下:
1撰糠、META-INF
????META是Meta Data的縮寫酥馍,元數(shù)據(jù)是描述數(shù)據(jù)的數(shù)據(jù),APK是一個壓縮包阅酪,可以認為是一種數(shù)據(jù)結(jié)構(gòu)旨袒,那它的Meta-data就是描述這個APK相關(guān)信息的數(shù)據(jù),比如使用三方庫版本號术辐、JAR包簽名(V1簽名文件砚尽,V2簽名等會是簽名在包裝APK之上,打開后就破壞了這個簽名)等辉词。
2必孤、res
????res目錄下包含了整個APP工程的資源,就是說打包時候會把一個APP所有模塊瑞躺,依賴庫中的資源挑選出來敷搪,進行合并 、縮減(比如開啟R8優(yōu)化幢哨,工程種沒有使用的資源就不會打包到APK)赡勘,重命名等操作,最后整理出來一份資源放這里捞镰,它對應(yīng)著我們工程目錄中的資源目錄:
image.png

3闸与、AndroidManifest.xml
????AndroidManifest.xml包含了整個APP所有模塊的配置文件,就是說打包時候會把一個APP所有模塊岸售、依賴庫中的AndroidManifest文件拿出來合并几迄、優(yōu)化得到這一份總的AndroidManifest配置文件。
4冰评、classes.dex
????classes.dex 文件是 對應(yīng)Android 工程中的Java和Kotlin源碼,是他們經(jīng)過編譯后生成的 Android虛擬機(Dalvik木羹、ART) Executable(可執(zhí)行) 文件甲雅,.dex 后綴就是 Dalvik Excecutable的縮寫解孙。
5、resources.arsc
????resources.arsc是所有模塊的資源地址映射表合集抛人, 就是說我們在代碼中尋找資源是 R.id.XX弛姜,但是實際讀一個文件是需要文件路徑的,這個文件就是把Id映射為路徑的表妖枚。
6廷臼、assets
????assets目錄就是我們原來放在各個模塊assets目錄下的so、圖片绝页、apk等文件的合集荠商,這部分是直接移動復(fù)制過來,沒有優(yōu)化续誉、沒有壓縮莱没,所以搞包體積優(yōu)化這地方是重點。
7酷鸦、lib目錄
????lib目錄存儲了整個工程的所有so文件饰躲,這些so文件來源于本模塊、依賴模塊臼隔、依賴庫等地方嘹裂,如果能夠確定每個渠道包對應(yīng)的設(shè)備使用CPU架構(gòu),可以在Android默配置摔握、flavor 中配置寄狼, 配置后就只打包需要的SO文件,使用這個配置能有效減少APK包體積大小如下圖:
cpu架構(gòu)支持配置.png

接下來就談?wù)勥@些產(chǎn)物是如何生成的盒发,Android官方給出的App打包詳細流轉(zhuǎn)圖如下:

image.png

注意:

  • 這些流程是配置階段決定好的例嘱,執(zhí)行階段就是按找之前決定的進行執(zhí)行;
  • 只要沒有先后順序的任務(wù)都是可以并行執(zhí)行的宁舰,Gradle也是多線程工作的拼卵;

名詞解釋
AAPT
aapt 是Android Asset Packaging Tool的縮寫,是編譯和打包資源的工具蛮艰,在SDK的build-tools目錄下腋腮。

ApkBuilder
ApkBuilder 相當于一個壓縮工具,它可以將已經(jīng)編譯好的 Java 代碼壤蚜、資源文件即寡、AndroidManifest.xml等打包成一個 ZIP 文件,即 APK 文件

參考文檔

https://docs.gradle.org/current/userguide/build_lifecycle.html#sec:build_phases

https://blog.csdn.net/qq_38056514/article/details/127292335

https://docs.gradle.org/current/javadoc/org/gradle/api/Project.html

https://juejin.cn/post/7113713363900694565

http://tools.android.com/tech-docs/new-build-system/build-workflow

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載袜刷,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者聪富。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市著蟹,隨后出現(xiàn)的幾起案子墩蔓,更是在濱河造成了極大的恐慌梢莽,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件奸披,死亡現(xiàn)場離奇詭異昏名,居然都是意外死亡,警方通過查閱死者的電腦和手機阵面,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進店門轻局,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人样刷,你說我怎么就攤上這事仑扑。” “怎么了颂斜?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵夫壁,是天一觀的道長。 經(jīng)常有香客問我沃疮,道長盒让,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任司蔬,我火速辦了婚禮邑茄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘俊啼。我一直安慰自己肺缕,他們只是感情好,可當我...
    茶點故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布授帕。 她就那樣靜靜地躺著同木,像睡著了一般。 火紅的嫁衣襯著肌膚如雪跛十。 梳的紋絲不亂的頭發(fā)上彤路,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天,我揣著相機與錄音芥映,去河邊找鬼洲尊。 笑死,一個胖子當著我的面吹牛奈偏,可吹牛的內(nèi)容都是我干的坞嘀。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼惊来,長吁一口氣:“原來是場噩夢啊……” “哼丽涩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起裁蚁,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤矢渊,失蹤者是張志新(化名)和其女友劉穎检眯,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體昆淡,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年刽严,在試婚紗的時候發(fā)現(xiàn)自己被綠了昂灵。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,096評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡舞萄,死狀恐怖眨补,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情倒脓,我是刑警寧澤撑螺,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站崎弃,受9級特大地震影響甘晤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜饲做,卻給世界環(huán)境...
    茶點故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一线婚、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧盆均,春花似錦塞弊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肮砾,卻和暖如春诀黍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背唇敞。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工蔗草, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疆柔。 一個月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓咒精,卻偏偏與公主長得像,于是被迫代替她去往敵國和親旷档。 傳聞我的和親對象是個殘疾皇子模叙,可洞房花燭夜當晚...
    茶點故事閱讀 45,037評論 2 355

推薦閱讀更多精彩內(nèi)容