Android Studio的編譯時(shí)間非常長(zhǎng),提示一直在解決模塊依賴(lài),點(diǎn)擊sync按鈕同步第三方代碼的時(shí)候也是巨慢,所以研究一下Androidstudio 編譯過(guò)程
先說(shuō)說(shuō)gradle 的生命周期吧,gradle 構(gòu)建一個(gè)工程主要分為三部分(完全掌握了下面這張圖,整個(gè) gradle 的構(gòu)建過(guò)程能了解個(gè)十之七八了):

- 初始化階段:主要是解析 setting.gradle 文件(因此有人提到減少 setting.gradle 的 module 數(shù)量,是很有道理的,但是實(shí)際操作過(guò)程限制頗多,原因最后會(huì)大致說(shuō)一下);
- 讀取配置階段:主要是解析所有的 projects 下的 build.gradle 文件,包括 rootProject 和其他的 subprojects(子項(xiàng)目),檢查語(yǔ)法,確定 tasks 依賴(lài)以建立 task 的有向無(wú)循環(huán)圖,檢查 task 里引用的文件目錄是否存在等(這一步也進(jìn)一步驗(yàn)證了減少 setting.gradle 里的 module 數(shù)量可以加快編譯速度,因?yàn)闇p少一個(gè) module ,需要解析的 build.gradle 文件就減少一個(gè),第 3 步里就不會(huì)執(zhí)行本屬于這個(gè) module 的任務(wù)了,但是還是 1 里面說(shuō)的問(wèn)題,限制頗多);
- 階段:按照 2 中建立的有向無(wú)循環(huán)圖來(lái)執(zhí)行每一個(gè) task ,整個(gè)編譯過(guò)程中,這一步基本會(huì)占去 9 成以上的時(shí)間,尤其是對(duì)于 Android 項(xiàng)目來(lái)講,將 java 轉(zhuǎn)為 class.
compileDebugJavaWithJavac/compileReleaseJavaWithJavac
和將 class 合并成 dex
transformClassesWithDexForDebug/transformClassesWithDexForRelease
這兩步很耗時(shí),第一步還好,第二步會(huì)耗時(shí)非常久。首先在 gradle.properties 里設(shè)置
org.gradle.jvmargs=-Xmx4096m //越大越好
然后在工程的 build.gradle 里的 android 結(jié)點(diǎn)下增加 dexOptions 配置,如下:
dexOptions {
dexInProcess true
preDexLibraries true
javaMaxHeapSize "4g"http://越大越好
incremental true
}
明確了 gradle 的生命周期,那么就可以看到加快編譯速度的關(guān)鍵就是從第三步入手,當(dāng)然,減少 setting.gradle 里的 modules 數(shù)量這一步也是必須的
在gradle中引用第三方模塊時(shí)采用maven方式依賴(lài),每次打開(kāi)Android Studio或者點(diǎn)擊sync按鈕時(shí),都會(huì)去maven中央倉(cāng)庫(kù)去取第三方的庫(kù)文件,一般是jar或者aar文件,如果本地沒(méi)有該文件,則下載回來(lái),由于通過(guò)網(wǎng)絡(luò)訪問(wèn)Android Studio默認(rèn)的maven中央倉(cāng)庫(kù)jcenter很慢,因此就導(dǎo)致同步會(huì)非常耗時(shí),尤其是第一次同步,或者clean后重新build的時(shí)候,一般都會(huì)在十分鐘左右,即使庫(kù)文件已經(jīng)下載到本地了,也會(huì)去訪問(wèn)maven倉(cāng)庫(kù)的,因此當(dāng)過(guò)多的通過(guò)maven方式依賴(lài)第三方庫(kù)的時(shí)候Android Studio就會(huì)非常慢
解決辦法
方法一:
(1) 當(dāng)?shù)谝淮瓮酱a后,第三方庫(kù)都下載到本地了,將gradle設(shè)置為offline模式,這樣下次就不必訪問(wèn)網(wǎng)絡(luò)了,這樣同步速度從幾分鐘縮短到幾秒鐘,但缺點(diǎn)是一旦引入新的maven依賴(lài),本地不存在這個(gè)庫(kù)文件,還是得去訪問(wèn)網(wǎng)絡(luò),同樣同步慢
方法二:
(2) 自己搭建maven倉(cāng)庫(kù),將常用的第三方庫(kù)放在自己搭建的maven服務(wù)器上,這樣訪問(wèn)內(nèi)部的maven服務(wù)器就快多了,又方便分模塊開(kāi)發(fā)和打包,但這樣對(duì)服務(wù)器的管理麻煩,技術(shù)含量高,比較適合需要分模塊開(kāi)發(fā)的大型項(xiàng)目,而且當(dāng)多個(gè)模塊開(kāi)發(fā)不同步,需要對(duì)模塊分版本進(jìn)行依賴(lài)、打包、發(fā)布的時(shí)候,必須采用這種方式,例如:模塊A已經(jīng)開(kāi)發(fā)完畢,模塊B正在開(kāi)發(fā),但這個(gè)時(shí)候要發(fā)版本了,怎么辦呢?解決辦法就是依賴(lài)模塊B的上個(gè)版本,也就是上個(gè)版本的aar文件
方法三:
(3) 將第三方庫(kù)下載到本地,然后將代碼復(fù)制到自己的項(xiàng)目中,這種方法是在代碼級(jí)別上直接使用別人的代碼,優(yōu)點(diǎn)是再也不用依賴(lài)別人的庫(kù),項(xiàng)目模塊少,庫(kù)與自己項(xiàng)目融為一體,缺點(diǎn)是復(fù)制的時(shí)候太辛苦了,不僅要復(fù)制代碼文件,還要復(fù)制資源文件,容易出錯(cuò),另外耦合比較嚴(yán)重,刪除這個(gè)庫(kù)的時(shí)候也非常麻煩,同時(shí)別人的代碼也破壞了自己的代碼風(fēng)格和命名規(guī)范
方法四:
(4) 推薦的方法是:盡量使用第三方庫(kù)的jar、aar文件導(dǎo)入自己的項(xiàng)目,或者將第三方庫(kù)下載到本地,然后當(dāng)做一個(gè)本地模塊導(dǎo)入自己的項(xiàng)目,不要再使用gradle中的maven依賴(lài)了
這樣就不用苦逼的去復(fù)制代碼,刪除的時(shí)候也很方便,只需刪除模塊即可,實(shí)現(xiàn)模塊即插即用,缺點(diǎn)是會(huì)導(dǎo)致項(xiàng)目的模塊太多,不美觀,以及很多eclipse寫(xiě)的庫(kù)導(dǎo)入Android Studio后還要自己修改才能編譯通過(guò),很多庫(kù)是Android工程,不是標(biāo)準(zhǔn)意義的Android library,
好在現(xiàn)在很多有名的庫(kù)都專(zhuān)門(mén)提供了library,直接導(dǎo)入即可,還有Android Studio已經(jīng)可以直接將eclipse工程當(dāng)做一個(gè)module導(dǎo)入了,所以這種方法還是很簡(jiǎn)單的
這種方法也就是以前eclipse使用第三方庫(kù)的方法
上面講到的幾點(diǎn),現(xiàn)有環(huán)境就可以做到的大概是這樣(有一點(diǎn)要特別注意,如果工程里有交叉依賴(lài),一定不要使用 --parallel 參數(shù)):
gradle assembleDebug --daemon --parallel -x lint -x test
如果是要直接安裝到設(shè)備上的話(huà),就把 assembleDebug 換成 installDebug ,assembleDebug 可以簡(jiǎn)寫(xiě)為 asD ,installDebug 可以簡(jiǎn)寫(xiě)為 iD