Android Note - 代碼構(gòu)建速度優(yōu)化

前言

很久沒寫了,這篇算是重啟了

最近因?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)

Android Studio 和 SDK 工具

Android Plugin for Gradle

為開發(fā)創(chuàng)建構(gòu)建變體

即為生產(chǎn)環(huán)境與開發(fā)環(huán)境分開配置productFlavors

避免編譯不必要的資源

您可以僅為devproductFlavors指定一個(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)建速度慢的原因

Optimize your build speed

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末揍堰,一起剝皮案震驚了整個(gè)濱河市鹏浅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌屏歹,老刑警劉巖隐砸,帶你破解...
    沈念sama閱讀 211,561評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異蝙眶,居然都是意外死亡季希,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,218評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來式塌,“玉大人博敬,你說我怎么就攤上這事》宄ⅲ” “怎么了偏窝?”我有些...
    開封第一講書人閱讀 157,162評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)境析。 經(jīng)常有香客問我囚枪,道長(zhǎng)派诬,這世上最難降的妖魔是什么劳淆? 我笑而不...
    開封第一講書人閱讀 56,470評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮默赂,結(jié)果婚禮上沛鸵,老公的妹妹穿的比我還像新娘。我一直安慰自己缆八,他們只是感情好曲掰,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,550評(píng)論 6 385
  • 文/花漫 我一把揭開白布力九。 她就那樣靜靜地躺著枉氮,像睡著了一般潮针。 火紅的嫁衣襯著肌膚如雪震庭。 梳的紋絲不亂的頭發(fā)上茎芋,一...
    開封第一講書人閱讀 49,806評(píng)論 1 290
  • 那天疫粥,我揣著相機(jī)與錄音彩库,去河邊找鬼穆碎。 笑死瑟啃,一個(gè)胖子當(dāng)著我的面吹牛论泛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蛹屿,決...
    沈念sama閱讀 38,951評(píng)論 3 407
  • 文/蒼蘭香墨 我猛地睜開眼屁奏,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了错负?” 一聲冷哼從身側(cè)響起坟瓢,我...
    開封第一講書人閱讀 37,712評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎犹撒,沒想到半個(gè)月后载绿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,166評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡油航,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,510評(píng)論 2 327
  • 正文 我和宋清朗相戀三年崭庸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,643評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怕享,死狀恐怖执赡,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情函筋,我是刑警寧澤沙合,帶...
    沈念sama閱讀 34,306評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站跌帐,受9級(jí)特大地震影響首懈,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜谨敛,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,930評(píng)論 3 313
  • 文/蒙蒙 一究履、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧脸狸,春花似錦最仑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,745評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至卿啡,卻和暖如春吟吝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背颈娜。 一陣腳步聲響...
    開封第一講書人閱讀 31,983評(píng)論 1 266
  • 我被黑心中介騙來泰國打工剑逃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人揭鳞。 一個(gè)月前我還...
    沈念sama閱讀 46,351評(píng)論 2 360
  • 正文 我出身青樓炕贵,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親野崇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子称开,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,509評(píng)論 2 348

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