日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
Android全量編譯加速——(透明依賴)

1.1. 背景

在我們平常的開(kāi)發(fā)中構(gòu)建工程是一個(gè)基礎(chǔ)的環(huán)節(jié),決定著開(kāi)發(fā)效率的高低,然而隨著業(yè)務(wù)代碼不斷累積,編譯耗時(shí)也隨之增長(zhǎng)。雖然已經(jīng)有許多增量編譯加速方案,但不可避免的在很多場(chǎng)景,還是需要全量編譯。而對(duì)于全量編譯加速,我們遇到了一些困難:

為桐城等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及桐城網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、桐城網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專(zhuān)業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!

  • K歌的項(xiàng)目里,總代碼量160w行,Kotlin代碼占比43%左右,編譯耗時(shí)占比卻高達(dá)70%,必須要壓縮這個(gè)比例。

于是需要找到一種方法,既能繼續(xù)享受kotlin帶來(lái)的開(kāi)發(fā)便利,也能緩解全量編譯時(shí)間快速增長(zhǎng)的問(wèn)題。

1.2. 方案

如果能減少kotlin的編譯數(shù)量,就能降低編譯耗時(shí),要么減少代碼,要么提前編譯代碼,后者可行度高。

而Android里支持兩種二進(jìn)制歸檔文件:JAR、AAR

兩種格式里源碼都是以.class格式存在,不過(guò)jar不包含資源,對(duì)于在做組件化的項(xiàng)目不友好,library module在編譯后會(huì)直接生成aar。

那么只要把所有l(wèi)ibrary module都通過(guò)CI/CD工具,持續(xù)的自動(dòng)生成aar,發(fā)布到同一個(gè)maven倉(cāng)庫(kù),在編譯時(shí)用這些aar參與編譯就成功了。

1.3. 方案初步呈現(xiàn)

 

library modules提前編譯成了aar,我們需要把依賴類(lèi)型由implementation project更改為implementation aar。

如果library module代碼改變了,都需要重復(fù)執(zhí)行提前編譯aar,修改依賴版本號(hào),很浪費(fèi)時(shí)間,這里能不能取締這個(gè)重復(fù)操作環(huán)節(jié)讓程序自動(dòng)化?

一種更好的方式:編譯時(shí)判斷l(xiāng)ibrary module當(dāng)前代碼版本是否有可用的aar,有則使用aar參與編譯。拆解流程:

計(jì)算當(dāng)前代碼版本所有文件的hash,包含如下:

  • JavaSource
  • JavaResource
  • Assets
  • Resources
  • Aidl
  • JniLibs
  • AndroidManifest.xml
  • Proguard
  • Lint

判斷maven倉(cāng)庫(kù)里是否有對(duì)應(yīng)hash的aar,尋址 = repository/libraryName/version-md5

修改library module依賴類(lèi)型為aar。

1.4. 遇到的問(wèn)題

1. jar重復(fù)類(lèi)沖突

可以看到B對(duì)C存在直接的依賴關(guān)系,這個(gè)關(guān)系會(huì)聲明在B.arr的元數(shù)據(jù)文件.pom,又由于C的代碼更改了導(dǎo)致無(wú)法匹配遠(yuǎn)程aar,所以最后C會(huì)同時(shí)以aar和project兩種方式參與編譯,如果C里包含了jar,就會(huì)沖突。

2. 工程重復(fù)類(lèi)沖突

share_m和share是同一個(gè)代碼倉(cāng)庫(kù),開(kāi)發(fā)便于驗(yàn)證更改了name,路由不一樣代碼一樣,gradle認(rèn)為是兩個(gè)aar,報(bào)錯(cuò)重復(fù)。

3. 三方庫(kù)版本沖突

最終編譯后share代碼版本依然為1.2.0,因?yàn)锽.aar存在對(duì)share:1.2.0依賴。Gradle將考慮所有請(qǐng)求的版本,無(wú)論它們出現(xiàn)在依賴關(guān)系圖中的何處。在這些版本中,它將選擇最高的版本。

第一個(gè)問(wèn)題:明顯的需要把B(aar)—>C(aar)這個(gè)依賴項(xiàng)解除,這里常用有兩個(gè)辦法:

  • 直接從pom里刪除該項(xiàng)依賴元數(shù)據(jù)(K歌采用)。
  • 修改B依賴C的依賴類(lèi)型改為compileOnly,不過(guò)如果B使用了C的資源打包aar會(huì)報(bào)錯(cuò)。

第二個(gè)問(wèn)題:K歌的做法是要求name保持一致,開(kāi)發(fā)修改代碼發(fā)布時(shí)只改變version。

第三個(gè)問(wèn)題:因?yàn)檫@種模型也會(huì)存在正常開(kāi)發(fā)中,對(duì)于版本沖突,有以下幾項(xiàng)辦法:

  • 開(kāi)發(fā)時(shí)用更高的版本去覆蓋掉參與構(gòu)建的所有版本。
  • 修改B—>share:1.2.0依賴類(lèi)型為compileOnly,來(lái)解除傳遞依賴。
  • 如果一定要使用動(dòng)態(tài)版本號(hào)+,且低于參與構(gòu)建的版本,可以提取出白名單,從pom里刪除該項(xiàng)依賴,統(tǒng)一由app主module依賴(K歌采用)。
  • B在發(fā)布aar時(shí),不保留pom里對(duì)三方的任何依賴元數(shù)據(jù),編譯時(shí)統(tǒng)一由app依賴。

想要解決傳遞依賴的問(wèn)題還有常見(jiàn)的transitive,force,嚴(yán)格依賴等特性,K歌使用這些特性很少,考慮到要開(kāi)發(fā)透明,保持原有代碼,我們采用的都是直接修改pom文件依賴項(xiàng)來(lái)解除傳遞依賴。

從以上問(wèn)題不難看出,唯一標(biāo)識(shí)=自身內(nèi)容+依賴關(guān)系圖,所以在計(jì)算md5時(shí),我們也需要把依賴關(guān)系算進(jìn)去。什么時(shí)候可以獲取依賴圖?

Gradle的構(gòu)建生命周期分為3步:

1、初始化

Gradle支持單項(xiàng)目和多項(xiàng)目構(gòu)建。在初始化階段,Gradle確定將要參與構(gòu)建的項(xiàng)目,并為每個(gè)項(xiàng)目創(chuàng)建一個(gè)Project實(shí)例。

2、配置

在此階段,將配置項(xiàng)目對(duì)象。執(zhí)行作為構(gòu)建一部分的所有項(xiàng)目的構(gòu)建腳本。

3、執(zhí)行

Gradle確定要在配置階段創(chuàng)建和配置的任務(wù)子集。子集由傳遞給gradle命令的任務(wù)名稱參數(shù)和當(dāng)前目錄確定。然后Gradle執(zhí)行每個(gè)選定的任務(wù)。

明確在配置階段是執(zhí)行build.gradle,依賴圖生成后,可以在項(xiàng)目評(píng)估回調(diào)里(afterEvaluate)解析完成我們的操作。

K歌的app module依賴了全局所有的library module,在編譯時(shí)app最先收到評(píng)估回調(diào),只要這時(shí)修改app的依賴關(guān)系圖就能阻斷其余l(xiāng)ibrary module的后續(xù)配置流程,而這時(shí)library module并未評(píng)估完成,拿不到依賴關(guān)系圖就無(wú)法計(jì)算md5,只能手動(dòng)解析library module的build.gradle文件里的依賴配置。K歌的配置一部分直接申明在dependencies里,一部分提取成了統(tǒng)一管理versionConfigs.gradle。

需要注意的是,每個(gè)項(xiàng)目評(píng)估完整結(jié)束后再修改依賴圖是不安全的,Gradle會(huì)阻止。

 

1.5. 最終流程

  1. 構(gòu)建項(xiàng)目,處于配置階段時(shí)會(huì)執(zhí)行每個(gè)project的build.gradle,里面會(huì)確定下來(lái)依賴關(guān)系,在評(píng)估項(xiàng)目之后(afterEvaluate)收到通知。
  2. 解析配置里對(duì)于本地project類(lèi)型的依賴(DefaultProjectDependency),計(jì)算project的md5,計(jì)算包含的內(nèi)容為前面講訴的aar內(nèi)容,同時(shí)把project的依賴關(guān)系也要作為md5計(jì)算的范圍。
  3. 計(jì)算出md5后按照maven庫(kù)的尋址規(guī)則拼接到路徑上訪問(wèn)遠(yuǎn)端maven倉(cāng)庫(kù)是否存在此aar。
  4. 存在aar,則將本地project的依賴類(lèi)型改為遠(yuǎn)程aar依賴(DefaultExternalModuleDependency)。

 


新聞名稱:Android全量編譯加速——(透明依賴)
本文路徑:http://www.dlmjj.cn/article/cddgddg.html