優(yōu)化使用kotlin開(kāi)發(fā)Android app的編譯速度

團(tuán)隊(duì)使用kotlin挺長(zhǎng)時(shí)間了,一直以來(lái)都不太滿(mǎn)意kotlin的編譯速度,但是也能忍受。最近開(kāi)了一個(gè)新項(xiàng)目,有不少同事從java過(guò)來(lái)的,他們就實(shí)在是受不了,優(yōu)化編譯速度就變得很重要了。

優(yōu)化之前和之后的對(duì)比

在優(yōu)化之前我們的一次完整編譯時(shí)間是2分21秒

image.png

具體的耗時(shí)任務(wù)在Run Tasks中:


image.png

可以看到具體的耗時(shí)任務(wù)如上,主要是kapt相關(guān)的編譯和編譯kotlin代碼,以及最后的transformClassedWithXXX。

優(yōu)化之后的完整編譯時(shí)間31s

image.png

優(yōu)化之后的增量編譯時(shí)間15s

image.png

image.png

優(yōu)化步驟:

1.優(yōu)化gradle配置:

在項(xiàng)目根目錄創(chuàng)建一個(gè)gradle.properties文件

//開(kāi)啟gradle并行編譯,開(kāi)啟daemon,調(diào)整jvm內(nèi)存大小
org.gradle.daemon=true
org.gradle.configureondemand=true
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=1024m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8

//開(kāi)啟gradle緩存
org.gradle.caching=true
android.enableBuildCache=true

//開(kāi)啟kotlin的增量和并行編譯
kotlin.incremental=true
kotlin.incremental.java=true
kotlin.incremental.js=true
kotlin.caching.enabled=true
kotlin.parallel.tasks.in.project=true //開(kāi)啟kotlin并行編譯


//優(yōu)化kapt
kapt.use.worker.api=true  //并行運(yùn)行kapt1.2.60版本以上支持
kapt.incremental.apt=true  //增量編譯 kapt1.3.30版本以上支持
kapt.include.compile.classpath=false  //kapt avoiding 如果用kapt依賴(lài)的內(nèi)容沒(méi)有變化,會(huì)完全重用編譯內(nèi)容,省掉最上圖中的:app:kaptGenerateStubsDebugKotlin的時(shí)間

在上面的配置中,我們首先調(diào)整了gradle的配置,然后開(kāi)啟了緩存和kotlin和kapt的增量編譯。

如果項(xiàng)目中使用了kapt請(qǐng)使用最新版本的kapt,當(dāng)前寫(xiě)該文章時(shí)kapt的最新版本為1.3.31

優(yōu)化app的build.gradle

1.在項(xiàng)目的app目錄中的build.gradle文件中修改:

//如果有用到kapt添加如下配置
kapt {
    useBuildCache = true
    javacOptions {
        option("-Xmaxerrs", 500)
    }
}

//在Android代碼塊中添加如下配置:(可優(yōu)化最上圖中transformClassDexBuilderForDebug的時(shí)間)
android {
    dexOptions {
        preDexLibraries true
        maxProcessCount 8
    }
}

2.其他不太重要的優(yōu)化,好像對(duì)時(shí)間影響不算特別大
優(yōu)化版本號(hào)的配置,如果是debug版本不要使用動(dòng)態(tài)版本號(hào)

//原配置
defaultConfig {
    ...
    minSdkVersion 19
    targetSdkVersion 28
    versionCode gitVersionCode()
    versionName currentName()
    ...
}
//修改為
defaultConfig {
    ...
    minSdkVersion 19
    targetSdkVersion 28
    versionCode 1
    versionName "1.0.0"
    ...
}
applicationVariants.all { variant ->
    ...
    if (variant.buildType.name == "release") {
        versionName = currentName()
        versionCode = gitVersionCode()
    }
    ...
}

以前我們的配置上versionCode是使用的git的提交次數(shù)作為版本號(hào)的,在本地debug狀態(tài)的時(shí)候其實(shí)最好是寫(xiě)死版本號(hào),如果版本號(hào)變化會(huì)導(dǎo)致需要重新生成Manifest文件以及完整的編譯應(yīng)用,導(dǎo)致InstantRun無(wú)法使用(PS其實(shí)我們一直沒(méi)用InstantRun)。所以修改為寫(xiě)死版本號(hào),然后在applicationVariants中判斷如果是release才使用正常的版本號(hào)。然后還有一個(gè)就是使用依賴(lài)版本的時(shí)候,盡量不要使用+號(hào)的版本依賴(lài),使用固定版本號(hào)速度會(huì)更快。

喜歡點(diǎn)擊+關(guān)注哦

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容