




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
【移動應(yīng)用開發(fā)技術(shù)】Android編譯的知識點有哪些
本篇內(nèi)容主要講解“Android編譯的知識點有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強(qiáng)。下面就讓在下來帶大家學(xué)習(xí)“Android編譯的知識點有哪些”吧!Android編譯的基礎(chǔ)知識無論是微信的編譯優(yōu)化,還是Tinker項目,都涉及比較多的編譯相關(guān)知識,因此我在Android編譯方面研究頗多,經(jīng)驗也比較豐富。Android的編譯構(gòu)建流程主要包括代碼、資源以及NativeLibrary三部分,整個流程可以參考官方文檔的構(gòu)建流程圖。Gradle是Android官方的編譯工具,它也是GitHub上的一個開源項目。從Gradle的更新日志可以看到,當(dāng)前這個項目還更新得非常頻繁,基本上每一兩個月都會有新的版本。對于Gradle,我感覺最痛苦的還是GradlePlugin的編寫,主要是因為Gradle在這方面沒有完善的文檔,因此一般都只能靠看源碼或者斷點調(diào)試的方法。最近我所在的公司就準(zhǔn)備用Gradle搞一個渠道打包工具,對于項目的打包和構(gòu)建過程,也是深有體會。但是編譯實在太重要了,每個公司的情況又各不相同,必須強(qiáng)行造一套自己的“輪子”。已經(jīng)開源的項目有Facebook的Buck以及Google的Bazel。為什么要自己“造輪子”呢?主要有下面幾個原因:統(tǒng)一編譯工具。Facebook、Google都有專門的團(tuán)隊負(fù)責(zé)編譯工作,他們希望內(nèi)部的所有項目都使用同一套構(gòu)建工具,這里包括Android、Java、iOS、Go、C++等。編譯工具的統(tǒng)一優(yōu)化,所有項目都會受益;代碼組織管理架構(gòu)。Facebook和Google的代碼管理有一個非常特別的地方,就是整個公司的所有項目都放到同一個倉庫里面。因此整個倉庫非常龐大,所以他們也不會使用Git。目前Google使用的是Piper,F(xiàn)acebook是基于HG修改的,也是一種基于分布式的文件系統(tǒng);極致的性能追求。Buck和Bazel的性能的確比Gradle更好,內(nèi)部包含它們的各種編譯優(yōu)化。但是它們或多或少都有一些定制的味道,例如對Maven、JCenter這樣的外部依賴支持的也不是太好?!俺绦騿T最痛恨寫文檔,還有別人不寫文檔”,所以它們的文檔也是比較少的,如果想做二次定制開發(fā)會感到很痛苦。如果你想把編譯工具切換到Buck和Bazel,需要下很大的決心,而且還需要考慮和其他上下游項目的協(xié)作。當(dāng)然即使我們不去直接使用,它們內(nèi)部的優(yōu)化思路也非常值得我們學(xué)習(xí)和參考。Gradle、Buck、Bazel都是以更快的編譯速度、更強(qiáng)大的代碼優(yōu)化為目標(biāo),我們下面一起來看看它們做了哪些努力。編譯速度回想一下我們的Android開發(fā)生涯,在編譯這件事情上面究竟浪費(fèi)了多少時間和生命。正如前面我所說,編譯速度對團(tuán)隊效率非常重要。關(guān)于編譯速度,我們最關(guān)心的可能還是編譯Debug包的速度,尤其是增量編譯(incrementalbuild)的速度,我們希望可以做到更加快速的調(diào)試。正如下圖所示,我們每次代碼驗證都要經(jīng)過編譯和安裝兩個步驟。此處,我們從編譯時間和安裝時間兩個緯度來看Android的編譯速度。編譯時間。把Java或者Kotlin代碼編譯為“.class“文件,然后通過dx編譯為Dex文件。對于增量編譯,我們希望編譯盡可能少的代碼和資源,最理想情況是只編譯變化的部分。但是由于代碼之間的依賴,大部分情況這并不可行。這個時候我們只能退而求其次,希望編譯更少的模塊。AndroidPlugin3.0及以后的版本使用Implementation代替Compile,正是為了優(yōu)化依賴關(guān)系;安裝時間。我們要先經(jīng)過簽名校驗,校驗成功后會有一大堆的文件拷貝工作,例如APK文件、Library文件、Dex文件等。之后我們還需要編譯Odex文件,這個過程特別是在Android5.0和6.0會非常耗時。對于增量編譯,最好的優(yōu)化是直接應(yīng)用新的代碼,無需重新安裝新的APK。對于增量編譯,我先來講講Gradle的官方方案InstantRun。在AndroidPlugin2.3之前,它使用的Multidex實現(xiàn)。在AndroidPlugin2.3之后,它使用Android5.0新增的SplitAPK機(jī)制。如下圖所示,資源和Manifest都放在BaseAPK中,在BaseAPK中代碼只有InstantRun框架,應(yīng)用的本身的代碼都在SplitAPK中。InstantRun有三種模式,如果是熱交換和溫交換,我們都無需重新安裝新的SplitAPK,它們的區(qū)別在于是否重啟Activity。對于冷交換,我們需要通過adbinstall-multiple-r-t重新安裝改變的SplitAPK,應(yīng)用也需要重啟。雖然無論哪一種模式,我們都不需要重新安裝BaseAPK。這讓InstantRun看起來是不是很不錯,但是在大型項目里面,它的性能依然非常糟糕,主要原因是:多進(jìn)程問題?!癟heappwasrestartedsinceitusesmultipleprocesses”,如果應(yīng)用存在多進(jìn)程,熱交換和溫交換都不能生效。因為大部分應(yīng)用都會存在多進(jìn)程的情況,InstantRun的速度也就大打折扣。SplitAPK安裝問題。雖然SplitAPK的安裝不會生成Odex文件,但是這里依然會有簽名校驗和文件拷貝(APK安裝的乒乓機(jī)制)。這個時間需要幾秒到幾十秒,是不能接受的。Javac問題。在Gradle4.6之前,如果項目中運(yùn)用了AnnotationProcessor。那不好意思,本次修改以及它依賴的模塊都需要全量javac,而這個過程是非常慢的,可能會需要幾十秒。這個問題直到Gradle4.7才解決,關(guān)于這個問題原因的討論你可以參考這個Issue。你還可以看看這一個Issue:“fullrebuildifaclasscontainsaconstant”,假設(shè)修改的類中包含一個“publicstaticfinal”的變量,那同樣也不好意思,本次修改以及它依賴的模塊都需要全量javac。這是為什么呢?因為常量池是會直接把值編譯到其他類中,Gradle并不知道有哪些類可能使用了這個常量。詢問Gradle的工作人員,他們出給的解決方案是下面這個://
原來的常量定義:
public
static
final
int
MAGIC
=
23
//
將常量定義替換成方法:
public
static
int
magic()
{
return
23;
}對于大型項目來說,這肯定是不可行的。正如我在Issue中所寫的一樣,無論我們是不是真正改到這個常量,Gradle都會無腦的全量javac,這樣肯定是不對的。事實上,我們可以通過比對這次代碼修改,看看是否有真正改變某一個常量的值。但是可能用過阿里的Freeline或者蘑菇街的極速編譯的同學(xué)會有疑問,它們的方案為什么不會遇到Annotation和常量的問題?事實上,它們的方案在大部分情況比InstantRun更快,那是因為犧牲了正確性。也就是說它們?yōu)榱俗非蟾斓乃俣龋苯雍雎粤薃nnotation和常量改變可能帶來錯誤的編譯產(chǎn)物。InstantRun作為官方方案,它優(yōu)先保證的是100%的正確性。當(dāng)然Google的人也發(fā)現(xiàn)了InstantRun的種種問題,在AndroidStudio3.5之后,對于Android8.0以后的設(shè)備將會使用新的方案“ApplyChanges”代替InstantRun。目前我還沒找到關(guān)于這套方案更多的資料,不過我認(rèn)為應(yīng)該是拋棄了SplitAPK機(jī)制。一直以來,我心目中都有一套理想的編譯方案,這套方案安裝的BaseAPK依然只是一個殼APK,真正的業(yè)務(wù)代碼放到Assets的ClassesN.dex中,它的架構(gòu)圖如下。無需安裝。依然使用類似Tinker熱修復(fù)的方法,每次只把修改以及依賴的類插入到pathclassloader的最前方就可以,不熟悉的同學(xué)可以參考《微信Android熱補(bǔ)丁實踐演進(jìn)之路》中的Qzone方案;Oatmeal。為了解決首次運(yùn)行時Assets中ClassesN.dex的Odex耗時問題,我們可以使用“安裝包優(yōu)化“中講過的ReDex中的黑科技:Oatmeal。它可以在100毫秒以內(nèi)生成一個完全解釋執(zhí)行的Odex文件;關(guān)閉JIT。我們通過在AndroidManifest中添加android:vmSafeMode=“true”來關(guān)閉虛擬機(jī)的JIT優(yōu)化,這樣也就不會出現(xiàn)Tinker在AndroidN混合編譯遇到的問題。對于編譯速度的優(yōu)化,我還有幾個建議:更換編譯機(jī)器。對于實力雄厚的公司,直接更換Mac或者其他更給力的設(shè)備作為編譯機(jī),這種方式是最簡單的;BuildCache??梢詫⒋蟛糠植怀8淖兊捻椖坎痣x出去,并使用遠(yuǎn)端Cache模式保留編譯后的緩存;升級Gradle和SDKBuildTools。我們應(yīng)該及時去升級最新的編譯工具鏈,享受Google的最新優(yōu)化成果;使用Buck。無論是Buck的exopackage,還是代碼的增量編譯,Buck都更加高效。但我前面也說過,一個大型項目如果要切換到Buck,其實顧慮還是比較多的。在2014年初微信就接入了Buck,但是因為跟其他項目協(xié)作的問題,導(dǎo)致在2015年切換回Gradle方案。相比之下,可能目前最熱的Flutter中HotReload秒級編譯功能會更有吸引力。當(dāng)然最近幾個AndroidStudio版本,Google也做了大量的其他優(yōu)化,例如使用AAPT2替代了AAPT來編譯Android資源。AAPT2實現(xiàn)了資源的增量編譯,它將資源的編譯拆分成Compile和Link兩個步驟。前者資源文件以二進(jìn)制形式編譯Flat格式,后者合并所有的文件再打包。除了AAPT2,Google還引入了d8和R8,下面分別是Google提供的一些測試數(shù)據(jù),如下圖。那什么是d8和R8呢?除了編譯速度的優(yōu)化,它們還有哪些其他的作用?可以參考下面的介紹:AndroidD8和R8代碼優(yōu)化對于Debug包編譯,我們更關(guān)心速度。但是對于Release包來說,代碼的優(yōu)化更加重要,因為我們會更加在意應(yīng)用的性能。下面我就分別講講ProGuard、d8、R8和ReDex這四種我們可能會用到的代碼優(yōu)化工具。ProGuard在微信Release包12分鐘的編譯過程里,單獨ProGuard就需要花費(fèi)8分鐘。盡管ProGuard真的很慢,但是基本每個項目都會使用到它。加入了ProGuard之后,應(yīng)用的構(gòu)建過程流程如下:ProGuard主要有混淆、裁剪、優(yōu)化這三大功能,它的整個處理流程如下:其中優(yōu)化包括內(nèi)聯(lián)、修飾符、合并類和方法等30多種,具體介紹與使用方法你可以參考官方文檔。D8AndroidStudio3.0推出了d8,并在3.1正式成為默認(rèn)工具。它的作用是將“.class”文件編譯為Dex文件,取代之前的dx工具。d8除了更快的編譯速度之外,還有一個優(yōu)化是減少生成的Dex大小。根據(jù)Google的測試結(jié)果,大約會有3%~5%的優(yōu)化。R8R8在AndroidStudio3.1中引入,它的志向更加高遠(yuǎn),它的目標(biāo)是取代ProGuard和d8。我們可以直接使用R8把“.class”文件變成Dex。同時,R8還支持ProGuard中混淆、裁剪、優(yōu)化這三大功能。由于目前R8依然處于實驗階段,網(wǎng)上的介紹資料并不多,你可以參考下面這些資料:ProGuard和R8對比:ProGuardandR8:acomparisonofoptimizers。JakeWharton大神的博客最近有很多R8相關(guān)的文章:/blog/。R8的最終目的跟d8一樣,一個是加快編譯速度,一個是更強(qiáng)大的代碼優(yōu)化。ReDex如果說R8是未來想取代的ProGuard的工具,那Facebook的內(nèi)部使用的ReDex其實已經(jīng)做到了。Facebook內(nèi)部的很多項目都已經(jīng)全部切換到ReDex,不再使用ProGuard了。跟ProGuard不同的是,它直接輸入的對象是Dex,而不是“.class”文件,也就是它是直接針對最終產(chǎn)物的優(yōu)化,所見即所得。在前面的文章中,我已經(jīng)不止一次提到ReDex這個項目,因為它里面的功能實在是太強(qiáng)大了,具體可以參考專欄前面的文章《包體積優(yōu)化(上):如何減少安裝包大小?》。Interdex:類重排和文件重排、Dex分包優(yōu)化;Oatmeal:直接生成的Odex文件;StripDebugInfo:去除Dex中的Debug信息。此外,ReDex中例如TypeErasure和去除代碼中的Aceess方法也是非常不錯的功能,它們無論對包體積還是應(yīng)用的運(yùn)行速度都有幫助,因此我也鼓勵你去研究和實踐一下它們的用法和效果。但是ReDex的文檔也是萬年不更新的,而且里面摻雜了一些Facebook內(nèi)部定制的邏輯,所以它用起來的確非常不方便。目前我主要還是直接研究它的源碼,參考它的原理,然后再直接單獨實現(xiàn)。事實上,Buck里面其實也還有很多好用的東西,但是文檔里面依然什么都沒有提到,所以還是需要“readthesourcecode”。LibraryMerge和Relinker多語言拆分分包支持ReDex支持持續(xù)交付Gradle、Buck、Bazel它們代表的都是狹義上的編譯,我認(rèn)為廣義的編譯應(yīng)該包括打包構(gòu)建、CodeReview、代碼工程管理、代碼掃描等流程,也就是業(yè)界最近經(jīng)常提起的持續(xù)集成。目前最常用的持續(xù)集成工具有Jenkins、GitLabCI、TravisCI等,GitHub也有提供自己的持續(xù)集成服務(wù)。每個大公司都有自己的持續(xù)集成方案,例如騰訊的RDM、阿里的摩天輪、大眾點評的
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 個人出售房產(chǎn)合同范本
- 加裝空調(diào)工程合同范本
- 購房合同有購房合同范本
- 單位合伙建房合同范例
- 關(guān)于獨家合同范本
- 醫(yī)藥會議合同范本
- 單位給買車合同范本
- 化工項目整體承建合同范本
- 產(chǎn)品總經(jīng)銷合同范本
- 醫(yī)院加盟合同范本
- 【《張裕酒業(yè)公司盈利能力探究》論文】
- 醫(yī)療器械臨床試驗質(zhì)量管理規(guī)范培訓(xùn)
- 寒假社會實踐大學(xué)生返鄉(xiāng)
- 站樁的知識講座
- 杭州園區(qū)招商規(guī)劃方案
- 【物業(yè)】《維修資金管理與使用》培訓(xùn)課件
- HGT4134-2022 工業(yè)聚乙二醇PEG
- 鋁合金時效爐安全操作規(guī)程模版
- DB2201T 59-2023 冬季供暖運(yùn)行參數(shù)氣象指標(biāo)及分級
- 四川家庭農(nóng)場補(bǔ)貼標(biāo)準(zhǔn)2023年
- 智能人體秤市場需求分析報告
評論
0/150
提交評論