自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Android全量編譯加速——(透明依賴)

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

1.1. 背景

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

  • K歌的項目里,總代碼量160w行,kotlin代碼占比43%左右,編譯耗時占比卻高達70%,必須要壓縮這個比例。

于是需要找到一種方法,既能繼續(xù)享受kotlin帶來的開發(fā)便利,也能緩解全量編譯時間快速增長的問題。

1.2. 方案

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

而Android里支持兩種二進制歸檔文件:JAR、AAR

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

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

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

 

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

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

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

計算當前代碼版本所有文件的hash,包含如下:

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

判斷maven倉庫里是否有對應hash的aar,尋址 = repository/libraryName/version-md5

修改library module依賴類型為aar。

1.4. 遇到的問題

1. jar重復類沖突

 

可以看到B對C存在直接的依賴關系,這個關系會聲明在B.arr的元數據文件.pom,又由于C的代碼更改了導致無法匹配遠程aar,所以最后C會同時以aar和project兩種方式參與編譯,如果C里包含了jar,就會沖突。

2. 工程重復類沖突

share_m和share是同一個代碼倉庫,開發(fā)便于驗證更改了name,路由不一樣代碼一樣,gradle認為是兩個aar,報錯重復。

3. 三方庫版本沖突

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

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

  • 直接從pom里刪除該項依賴元數據(K歌采用)。
  • 修改B依賴C的依賴類型改為compileOnly,不過如果B使用了C的資源打包aar會報錯。

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

第三個問題:因為這種模型也會存在正常開發(fā)中,對于版本沖突,有以下幾項辦法:

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

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

從以上問題不難看出,唯一標識=自身內容+依賴關系圖,所以在計算md5時,我們也需要把依賴關系算進去。什么時候可以獲取依賴圖?

Gradle的構建生命周期分為3步:

1、初始化

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

2、配置

在此階段,將配置項目對象。執(zhí)行作為構建一部分的所有項目的構建腳本。

3、執(zhí)行

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

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

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

需要注意的是,每個項目評估完整結束后再修改依賴圖是不安全的,Gradle會阻止。

 

1.5. 最終流程

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

 

 

責任編輯:未麗燕 來源: 騰訊音樂技術團隊
相關推薦

2010-07-28 10:31:24

ADSL加速方法

2017-08-28 17:50:45

全閃存

2024-01-11 16:02:38

OHOS依賴關系檢查編譯構建系統(tǒng)

2009-02-24 09:28:00

2011-05-31 10:00:21

Android Spring 依賴注入

2015-12-30 14:17:56

微軟Windows 10Windows 7

2016-01-20 11:22:17

增量部署全量部署運維

2019-12-10 09:54:20

高德APP架構全鏈路

2023-03-09 15:15:21

鴻蒙模塊編譯

2015-12-08 11:11:33

戴爾云計算

2012-09-29 13:31:26

智匯云應用商店

2016-12-02 19:00:13

Android FraAndroid

2010-02-06 10:14:36

Android Act

2022-02-21 14:49:26

OpenHarmon操作系統(tǒng)鴻蒙

2025-02-24 12:22:13

DeepSeek開源模型

2021-09-16 17:00:37

工業(yè)控制應用
點贊
收藏

51CTO技術棧公眾號