前言
很久沒寫了,這篇算是重啟了
最近因?yàn)轫?xiàng)目的編譯速度越來越慢,嚴(yán)重到有時(shí)候甚至接近十分鐘才能完成一次完整編譯牍颈,就決定對(duì)著官方文檔對(duì)Gradle
進(jìn)行一番優(yōu)化。優(yōu)化完成后果然構(gòu)建速度得到大幅提升琅关,遂在此記錄
如何開始
由于是對(duì)照官方文檔并結(jié)合實(shí)際項(xiàng)目進(jìn)行優(yōu)化煮岁,所以某些細(xì)節(jié)或者項(xiàng)目中沒有用到的點(diǎn)就簡(jiǎn)略帶過
保持工具處于最新狀態(tài)
為開發(fā)創(chuàng)建構(gòu)建變體
即為生產(chǎn)環(huán)境與開發(fā)環(huán)境分開配置productFlavors
避免編譯不必要的資源
您可以僅為dev
的productFlavors
指定一個(gè)語言資源和屏幕密度
productFlavors {
dev {
resConfigs "en", "xxhdpi"
}
...
}
為您的調(diào)試構(gòu)建停用 Crashlytics(Fabric)
一般是在debug時(shí)停用
android {
...
buildTypes {
debug {
ext.enableCrashlytics = false
}
}
將靜態(tài)構(gòu)建配置值與調(diào)試構(gòu)建結(jié)合使用
始終為進(jìn)入
manifest
文件的屬性使用靜態(tài)/硬編碼值,或者為您的調(diào)試構(gòu)建類型使用資源文件涣易。如果您的manifest
文件或應(yīng)用資源中的值需要隨著每一個(gè)構(gòu)建更新画机,Instant Run
將無法執(zhí)行代碼交換 - 它必須構(gòu)建和安裝新的 APK
例如,在您每次想要運(yùn)行更改時(shí)新症,使用動(dòng)態(tài)版本代碼步氏、版本名稱、資源或任何其他可以更改
manifest
文件的構(gòu)建邏輯都需要一個(gè)完整的 APK 構(gòu)建 - 即使實(shí)際更改僅需要一個(gè)熱交換徒爹,也是如此荚醒。如果您的構(gòu)建配置需要此類動(dòng)態(tài)屬性,那么將其隔離到您的發(fā)布構(gòu)建變體中并讓值對(duì)您的調(diào)試構(gòu)建保持靜態(tài)
簡(jiǎn)單點(diǎn)來說隆嗅,就是如果gradle構(gòu)建中使用了動(dòng)態(tài)構(gòu)建配置界阁,那么Instant Run
就無法起到應(yīng)有的作用,與直接構(gòu)建新的APK沒有任何區(qū)別
下面是例子
int MILLIS_IN_MINUTE = 1000 * 60
int minutesSinceEpoch = System.currentTimeMillis() / MILLIS_IN_MINUTE
android {
...
defaultConfig {
versionCode 1
versionName "1.0"
...
}
applicationVariants.all { variant ->
if (variant.buildType.name == "release") {
variant.mergedFlavor.versionCode = minutesSinceEpoch;
variant.mergedFlavor.versionName = minutesSinceEpoch + "-" + variant.flavorName;
}
}
}
使用靜態(tài)依賴項(xiàng)版本
在build.gradle
文件中聲明依賴項(xiàng)時(shí)胖喳,您應(yīng)當(dāng)避免在結(jié)尾將版本號(hào)與加號(hào)一起使用泡躯,例如com.android.tools.build:gradle:2.+
使用動(dòng)態(tài)版本號(hào)可能導(dǎo)致意外版本更新和難以解析版本差異,并因 Gradle
檢查有無更新而減慢構(gòu)建速度。您應(yīng)改為使用靜態(tài)/硬編碼版本號(hào)
這個(gè)大家都懂精续,就不多說了
啟用離線模式
如果您的網(wǎng)絡(luò)連接速度比較慢,那么在
Gradle
嘗試使用網(wǎng)絡(luò)資源解析依賴項(xiàng)時(shí)粹懒,您的構(gòu)建時(shí)間可能會(huì)延長(zhǎng)重付。您可以指示Gradle
僅使用它已經(jīng)緩存到本地的工件來避免使用網(wǎng)絡(luò)資源
這個(gè)也是很常見的加快構(gòu)建速度的方式,尤其是在國內(nèi)凫乖,使用離線模式后構(gòu)建速度可以大大提升确垫。但是離線模式在每次引用新的依賴時(shí)會(huì)找不到依賴,所以新項(xiàng)目的話帽芽,還是能不用就不要用吧
啟用按需配置
為了讓 Gradle
準(zhǔn)確了解如何構(gòu)建您的應(yīng)用删掀,構(gòu)建系統(tǒng)會(huì)在每個(gè)構(gòu)建前在項(xiàng)目中配置所有模塊以及這些模塊的依賴項(xiàng)(即使您正在構(gòu)建和測(cè)試一個(gè)模塊,也是如此)导街。這會(huì)減慢大型多模塊項(xiàng)目的構(gòu)建進(jìn)程
注意:按需配置在新版的Android Studio中已經(jīng)沒有了
啟用并行化編譯
在嘗試按需配置的過程中發(fā)現(xiàn)Compile independent modules in parallel
這個(gè)選項(xiàng)披泪,查詢一番后發(fā)現(xiàn)是使用并行化編譯,能提高編譯速度搬瑰,勾選即可
在模塊化開發(fā)中款票,啟用并行化編譯提高編譯速度更為顯著
創(chuàng)建庫模塊
在應(yīng)用中查找您可以轉(zhuǎn)換成 Android 庫模塊的代碼。通過這種方式將您的代碼模塊化可以讓構(gòu)建系統(tǒng)僅編譯您修改的模塊泽论,并緩存這些輸出以用于未來構(gòu)建艾少。這種方式也會(huì)讓按需配置和并行項(xiàng)目執(zhí)行更有效(如果您啟用這些功能)
就是讓你把項(xiàng)目模塊化,不再贅述了
為自定義構(gòu)建邏輯創(chuàng)建任務(wù)
在您創(chuàng)建構(gòu)建分析后翼悴,如果分析顯示構(gòu)建時(shí)間中相當(dāng)大的一部分用在了“配置項(xiàng)目”階段缚够,請(qǐng)檢查 build.gradle 腳本并查找您可以添加到自定義 Gradle 任務(wù)中的代碼。將某個(gè)構(gòu)建邏輯移動(dòng)到任務(wù)中后鹦赎,它僅會(huì)在需要時(shí)運(yùn)行谍椅,可以為后續(xù)構(gòu)建緩存結(jié)果,并且該構(gòu)建邏輯將有資格并行運(yùn)行(如果您啟用并行項(xiàng)目執(zhí)行)古话。要了解詳情毯辅,請(qǐng)閱讀官方 Gradle 文檔。
就是讓你把一些不是必需執(zhí)行的構(gòu)建轉(zhuǎn)移到Task中執(zhí)行煞额,比如某個(gè)不需要在Debug時(shí)執(zhí)行的構(gòu)建
配置 dexOptions 和啟用庫預(yù) dexing
啟用這些配置可能加快構(gòu)建思恐,但是按官網(wǎng)說的,
您應(yīng)當(dāng)遞增這些設(shè)置的值來試驗(yàn)它們并通過分析您的構(gòu)建觀察效果膊毁。如果您向進(jìn)程分配過多的資源胀莹,性能可能會(huì)下降
所以這個(gè)還是得自己判斷是否開啟。至于具體的配置對(duì)應(yīng)的含義婚温,官網(wǎng)已經(jīng)寫得很清楚了描焰,就直接發(fā)出來
-
preDexLibraries
聲明是否預(yù) dex 庫依賴項(xiàng)以加快您的增量構(gòu)建速度。由于此功能可能減慢您的干凈構(gòu)建的速度,您可能需要為持續(xù)性集成服務(wù)器停用此功能荆秦。 -
maxProcessCount
設(shè)置運(yùn)行dex-in-process
時(shí)要使用的最大線程數(shù)量篱竭。默認(rèn)值為 4。 -
javaMaxHeapSize
設(shè)置 DEX 編譯器的最大堆大小步绸。不過掺逼,您應(yīng)當(dāng)增加Gradle
的堆大小(啟用dex-in-process
時(shí)瓤介,將與 DEX 編譯器共享)吕喘,而不是設(shè)置此屬性。
增加 Gradle 的堆大小并啟用 dex-in-process
在項(xiàng)目的 gradle.properties
文件中將 Gradle
的堆大小設(shè)置為 2048 MB:
org.gradle.jvmargs = -Xmx2048m
將圖像轉(zhuǎn)換成 WebP
這也是老生常談了刑桑,Android Studio里就能直接轉(zhuǎn)換氯质,不過我在項(xiàng)目中并沒有這么干
停用 PNG 處理
如果您無法(或者不想)將 PNG 圖像轉(zhuǎn)換成 WebP,仍可以通過在每次構(gòu)建應(yīng)用時(shí)停用自動(dòng)圖像壓縮的方式加快構(gòu)建速度祠斧。要停用此優(yōu)化闻察,請(qǐng)將以下代碼添加到您的 build.gradle
文件中:
android {
...
aaptOptions {
cruncherEnabled false
}
}
由于構(gòu)建類型或產(chǎn)品風(fēng)味不定義此屬性,在構(gòu)建發(fā)布版本的應(yīng)用時(shí)琢锋,您需要將此屬性手動(dòng)設(shè)置為 true
開啟了這個(gè)蜓陌,好像編譯速度又能快一個(gè)臺(tái)階
啟用 Instant Run
前面提到過了,前提是腳本中盡量使用靜態(tài)依賴吩蔑。由于目前項(xiàng)目中動(dòng)態(tài)依賴寫得太多钮热,所以這個(gè)暫時(shí)還是沒有用起來
啟用構(gòu)建緩存
使用 Android 插件 2.3.0 及更高版本的新項(xiàng)目在默認(rèn)情況下會(huì)啟用構(gòu)建緩存(除非您明確停用構(gòu)建緩存)
停用注解處理器
使用注解處理器(Annotation-Processing-Tool)時(shí),增量 Java 編譯處于停用狀態(tài)烛芬。如果可以隧期,請(qǐng)嘗試避免使用注解處理器,以便在不同構(gòu)建之間僅編譯您修改的類
那么多第三方庫用注解寫的赘娄,一般情況下不太可能停用注解處理
但是不使用Butterknife轉(zhuǎn)而使用findViewById確實(shí)能提高編譯速度仆潮,因?yàn)楸苊饬松蓪?duì)應(yīng)的注解類。建議在子元素不多或者頻繁生成時(shí)候直接findViewById
尾聲
其實(shí)就是一篇官網(wǎng)構(gòu)建速度優(yōu)化的讀后感遣臼,但按照提示一步步來性置,構(gòu)建速度提升確實(shí)比較明顯。下一篇會(huì)講講如何使用構(gòu)建分析工具來分析構(gòu)建速度慢的原因