Android App 構(gòu)建流程分析

我們平時(shí)在android studio中點(diǎn)擊run 衣屏,就能把代碼編譯成一個(gè)apk文件并安裝到手機(jī)上后添。那么這個(gè)過(guò)程中都具體發(fā)生了什么 ?我們是怎么把代碼和資源文件打包成一個(gè)apk文件,并安裝到手機(jī)上的呢 颇蜡? 今天就詳細(xì)研究一下這個(gè)流程 。

Apk構(gòu)建基本流程

build-simplified.png

上圖是Android官方提供的打包簡(jiǎn)略流程圖。清晰地展示了一個(gè)Android Project經(jīng)過(guò)編譯和打包后生成apk文件风秤,然后再經(jīng)過(guò)簽名鳖目,就可以安裝到設(shè)備上

我們將一個(gè)實(shí)際的apk文件后綴改為zip并解壓后,得到的內(nèi)容如下

apk_component_1.png

和上圖的描述一致缤弦。apk包內(nèi)容包括:

  • classes.dex…
  • resources.arsc
  • assets
  • res
  • AndroidManifest.xml
  • META-INF

其中:

  1. res中圖片和raw文件下內(nèi)容保持原樣疑苔,res中其他xml文件內(nèi)容均轉(zhuǎn)化為二進(jìn)制形式;assets文件內(nèi)容保持原樣
  2. res中的文件會(huì)被映射到R.java文件中甸鸟,訪問(wèn)的時(shí)候直接使用資源ID即R.id.filename惦费;assets文件夾下的文件不會(huì)被映射到R.java中,訪問(wèn)的時(shí)候需要AssetManager類

在看下這張圖 抢韭,android apk構(gòu)建詳細(xì)流程圖

QQ截圖20161230105534.png

打包步驟:

1. 通過(guò)aapt打包res資源文件薪贫,生成R.java、resources.arsc和res文件(二進(jìn)制 & 非二進(jìn)制如res/raw和pic保持原樣) 刻恭,詳細(xì)步驟如下

  • 檢查AndroidManifest.xml瞧省,主要做一些檢查并使用parsePackage初始化并設(shè)置一些attribute,比如package, minSdkVersion, uses-sdk鳍贾。

  • 添加被引用資源包使用table.addIncludedResources(bundle, assets)添加被引用資源包鞍匾,比如系統(tǒng)的那些android:命名空間下的資源。

  • 收集資源文件,處理overlay(重疊包骑科,如果指定的重疊包有和當(dāng)前編譯包重名的資源橡淑,則使用重疊包的):

  • 將收集到的資源文件加到資源表(ResourceTable)對(duì)res目錄下的各個(gè)資源子目錄進(jìn)行處理,函數(shù)為makeFileResources:makeFileResources會(huì)對(duì)資源文件名做合法性檢查咆爽,并將其添加到ResourceTable內(nèi)梁棠。

  • 編譯values資源并添加到資源表,在上一步添加過(guò)程中,其實(shí)并沒(méi)有對(duì)values資源進(jìn)行處理斗埂,因?yàn)関alues比較特殊符糊,需要經(jīng)過(guò)編譯之后,才能添加到資源表中呛凶。

  • 給bag資源分配id,在繼續(xù)編譯其他資源之前男娄,我們需要先給bag資源(attrs,比如orientation這種屬性的取值范圍定義的子元素)分配id漾稀,因?yàn)槠渌Y源可能對(duì)它們有引用模闲。

  • 編譯xml資源文件,最后我們終于可以編譯xml文件了,因?yàn)槲覀円呀?jīng)為它準(zhǔn)備好了一切可能引用到的東西(value, drawable等)县好。程序會(huì)對(duì)layouts, anims, animators等逐一調(diào)用

  • ResourceTable.cpp的,進(jìn)行編譯围橡,內(nèi)部流程又可以分為:解析xml文件,賦予屬性名稱資源id缕贡,解析屬性值翁授,扁平化為二進(jìn)制文件拣播。

  • 編譯AndroidManifest.xml文,拿到AndroidManifest.xml文件,清空原來(lái)的數(shù)據(jù),重新解,處理package name重載收擦,把各種相對(duì)路徑的名字改為絕對(duì)路徑,編譯manifest xml文件,生成最終資源表.9.生成R.java文件

生成我們解壓后看到的那個(gè)resources.arsc:

2. 處理.aidl文件贮配,生成對(duì)應(yīng)的Java接口文件

  • aidl,全名Android Interface Definition Language塞赂,即Android接口定義語(yǔ)言泪勒。
    輸入:aidl后綴的文件。輸出:可用于進(jìn)程通信的C/S端java代碼宴猾,位于build/generated/source/aidl圆存。

3. 通過(guò)Java Compiler編譯R.java、Java接口文件仇哆、Java源文件沦辙,生成.class文件

我們有了R.java和aidl生成的Java文件,再加上工程的源代碼讹剔,現(xiàn)在可以使用javac進(jìn)行正常的java編譯生成class文件了油讯。

輸入:java source的文件夾(另外還包括了build/generated下的:R.java, aidl生成的java文件,以及BuildConfig.java)延欠。輸出:對(duì)于gradle編譯陌兑,可以在build/intermediates/classes里,看到輸出的class文件由捎。

源碼編譯之后兔综,我們可能還會(huì)對(duì)其進(jìn)行代碼的混淆,混淆的作用是增加反編譯的難度隅俘,同時(shí)也將一些代碼的命名進(jìn)行了縮短邻奠,減少代碼占用的空間∥樱混淆完成之后,會(huì)生成一個(gè)混淆前后的映射表杀狡,這個(gè)是用來(lái)在反應(yīng)我們的應(yīng)用執(zhí)行的時(shí)候的一些堆棧信息蒙畴,可以將混淆后的信息轉(zhuǎn)化為我們混淆前實(shí)際代碼中的內(nèi)容。

4. 通過(guò)dex命令呜象,將.class文件和第三方庫(kù)中的.class文件處理生成classes.dex

調(diào)用dx.bat將所有的class文件(上一步生成的以及第三方庫(kù)的)轉(zhuǎn)化為classes.dex文件膳凝,dx會(huì)將class轉(zhuǎn)換為Dalvik字節(jié)碼,生成常量池恭陡,消除冗余數(shù)據(jù)等蹬音。

5. 通過(guò)apkbuilder工具,將aapt生成的resources.arsc和res文件休玩、assets文件和classes.dex一起打包生成apk

打包生成APK文件著淆。舊的apkbuilder腳本已經(jīng)廢棄劫狠,現(xiàn)在都已經(jīng)通過(guò)sdklib.jar的ApkBuilder類進(jìn)行打包了。輸入為我們之前生成的包含resources.arcs的.ap_文件永部,上一步生成的dex文件独泞,以及其他資源如jni、jar包內(nèi)的資源苔埋。

大致步驟為
以包含resources.arcs的.ap_文件為基礎(chǔ)懦砂,new一個(gè)ApkBuilder,設(shè)置debugMode
apkBuilder.addZipFile(f);
apkBuilder.addSourceFolder(f);
apkBuilder.addResourcesFromJar(f);
apkBuilder.addNativeLibraries(nativeFileList);
apkBuilder.sealApk(); // 關(guān)閉apk文件
generateDependencyFile(depFile, inputPaths, outputFile.getAbsolutePath());

6. 通過(guò)Jarsigner工具组橄,對(duì)上面的apk進(jìn)行debug或release簽名

對(duì)apk文件進(jìn)行簽名荞膘。APK需要簽名才能在設(shè)備上進(jìn)行安裝很多時(shí)候我們?cè)谀嫦蚋耐旰螅瑫?huì)因?yàn)闆](méi)有簽名文件導(dǎo)致最后的apk無(wú)法正常使用玉工,又細(xì)分為本地驗(yàn)證和服務(wù)器驗(yàn)證衫画。

7. 通過(guò)zipalign工具,將簽名后的apk進(jìn)行對(duì)齊處理瓮栗。

調(diào)用buildtoolszipalign削罩,對(duì)簽名后的apk文件進(jìn)行對(duì)齊處理欣舵,使apk中所有資源文件距離文件起始偏移為4字節(jié)的整數(shù)倍荆永,從而在通過(guò)內(nèi)存映射訪問(wèn)apk文件時(shí)會(huì)更快。同時(shí)也減少了在設(shè)備上運(yùn)行時(shí)的內(nèi)存消耗释牺。這樣我們的最終apk就生成完畢了愿阐。

關(guān)于zipalign工具微服,根據(jù)名字就知道是個(gè)zip文件對(duì)齊的工具。使得apk中的資源文件偏離文件起始位置4個(gè)字節(jié)缨历,從而可以通過(guò)mmap()直接訪問(wèn)以蕴,從而減少RAM占用。

參考文檔

1辛孵、官網(wǎng) :配置構(gòu)建
2丛肮、apk 構(gòu)建流程
3、Android打包系列——打包流程梳理
4魄缚、APK打包安裝過(guò)程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末宝与,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子冶匹,更是在濱河造成了極大的恐慌习劫,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嚼隘,死亡現(xiàn)場(chǎng)離奇詭異诽里,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)飞蛹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門谤狡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)灸眼,“玉大人,你說(shuō)我怎么就攤上這事豌汇〈闭ǎ” “怎么了?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵拒贱,是天一觀的道長(zhǎng)宛徊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)逻澳,這世上最難降的妖魔是什么闸天? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮斜做,結(jié)果婚禮上苞氮,老公的妹妹穿的比我還像新娘。我一直安慰自己瓤逼,他們只是感情好笼吟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著霸旗,像睡著了一般贷帮。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上诱告,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天撵枢,我揣著相機(jī)與錄音,去河邊找鬼精居。 笑死锄禽,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的靴姿。 我是一名探鬼主播沃但,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼空猜!你這毒婦竟也來(lái)了绽慈?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤辈毯,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后搜贤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谆沃,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年仪芒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唁影。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耕陷。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖据沈,靈堂內(nèi)的尸體忽然破棺而出哟沫,到底是詐尸還是另有隱情,我是刑警寧澤锌介,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布嗜诀,位于F島的核電站,受9級(jí)特大地震影響孔祸,放射性物質(zhì)發(fā)生泄漏隆敢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一崔慧、第九天 我趴在偏房一處隱蔽的房頂上張望拂蝎。 院中可真熱鬧,春花似錦惶室、人聲如沸温自。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)悼泌。三九已至,卻和暖如春鹅士,著一層夾襖步出監(jiān)牢的瞬間券躁,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工掉盅, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留也拜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓趾痘,卻偏偏與公主長(zhǎng)得像慢哈,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子永票,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

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