建構時間越長,開發過程就越慢。本頁介紹了一些技巧,可幫助您解決建構速度瓶頸。
改善應用程式建構速度的一般程序如下:
在開發應用程式時,您應盡可能部署至搭載 Android 7.0 (API 級別 24) 以上版本的裝置。這是因為較新版的 Android 平台在推送更新到應用程式時,可以提供更好的作業機制,例如 Android 執行階段 (ART) 以及對多個 DEX 檔案的原生支援。
注意:第一次進行建構清理後,您可能會發現後續的清理和漸進式建構速度變快許多,即使並未採行本頁所述的任何最佳化措施。這是因為 Gradle Daemon 有一個增加效能的「暖身」時間,這與其他 JVM 過程類似。
最佳化建構設定
請按照下列提示來提升 Android Studio 專案的建構速度。
確認工具為最新版本
幾乎每一次更新後,Android 工具都會實現建構最佳化並收到新功能。本頁中的某些提示假設您使用的是最新版本。為了充分利用最新的最佳化功能,請確保以下項目為最新版本:
避免編譯不必要的資源
請勿編譯及封裝非測試中的資源,例如其他語言本地化和螢幕密度資源。而只需為您的「dev」版本指定一種語言資源和螢幕密度即可,如下列範例所示:
Groovy
android { ... productFlavors { dev { ... // The following configuration limits the "dev" flavor to using // English stringresources and xxhdpi screen-density resources. resourceConfigurations "en", "xxhdpi" } ... } }
Kotlin
android { ... productFlavors { create("dev") { ... // The following configuration limits the "dev" flavor to using // English stringresources and xxhdpi screen-density resources. resourceConfigurations("en", "xxhdpi") } ... } }
嘗試將 Gradle 外掛程式入口網站放在最後
在 Android 中,所有外掛程式都位於 google()
和 mavenCentral()
存放區。但是,您的版本可能需要使用 gradlePluginPortal()
服務解析的第三方外掛程式。
Gradle 會依照宣告的順序搜尋存放區,因此如果優先列出的存放區含有大部分的外掛程式,建構效能就會有所提升。因此,您可以嘗試將 gradlePluginPortal()
項目放到 settings.gradle
檔案中存放區區塊的最後位置。在多數情況下,這可盡量減少冗餘外掛程式的搜尋次數,並提升建構速度。
如要進一步瞭解 Gradle 如何瀏覽多個存放區,請參閱 Gradle 文件中的宣告多個存放區一文。
對偵錯版本使用靜態建構設定值
對於偵錯建構類型,務必對資訊清單檔案或資源檔案中的屬性使用靜態值。
如果您使用動態版本代碼、版本名稱、資源或其他可變更資訊清單檔案的建構邏輯,則每次執行變更都必須完成完整的應用程式建構作業,即使實際的變更可能只需要熱切換也一樣。如果您的建構設定需要這類動態屬性,請將這些屬性與發布建構變數區隔開來,並保持偵錯建構作業的值為靜態,如以下範例所示:
... // Use a filter to apply onVariants() to a subset of the variants. onVariants(selector().withBuildType("release")) { variant -> // Because an app module can have multiple outputs when using multi-APK, versionCode // is only available on the variant output. // Gather the output when we are in single mode and there is no multi-APK. val mainOutput = variant.outputs.single { it.outputType == OutputType.SINGLE } // Create the version code generating task. val versionCodeTask = project.tasks.register("computeVersionCodeFor${variant.name}", VersionCodeTask::class.java) { it.outputFile.set(project.layout.buildDirectory.file("versionCode${variant.name}.txt")) } // Wire the version code from the task output. // map will create a lazy Provider that: // 1. Runs just before the consumer(s), ensuring that the producer (VersionCodeTask) has run // and therefore the file is created. // 2. Contains task dependency information so that the consumer(s) run after the producer. mainOutput.versionCode.set(versionCodeTask.flatMap { it.outputFile.map { it.asFile.readText().toInt() } }) } ... abstract class VersionCodeTask : DefaultTask() { @get:OutputFile abstract val outputFile: RegularFileProperty @TaskAction fun action() { outputFile.get().asFile.writeText("1.1.1") } }
如要瞭解在專案中設定動態版本代碼的方法,請參閱 GitHub 上的「setVersionsFromTask recipe」。
使用靜態依附元件版本
在 build.gradle
檔案中宣告依附元件時,請避免使用動態版本號碼 (末尾帶有加號的版本號碼,例如 'com.android.tools.build:gradle:2.+'
)。使用動態版本號碼可能會導致非預期的版本更新、難以解決版本差異,以及因 Gradle 檢查更新造成建構速度變慢的問題。請改用靜態版本號碼。
建立程式庫模組
在應用程式中,找出可轉換為 Android 程式庫模組的程式碼。以這種方式模組化程式碼可讓建構系統僅編譯您修改的模組,並快取這些輸出內容以供日後建構使用。啟用最佳化功能時,模組化還能提高平行專案執行作業的效率。
建立自訂建構邏輯的工作
建立建構設定檔後,如果建構設定檔顯示在**設定專案**階段花費的建構時間相對較長,請審查您的 build.gradle
指令碼,然後尋找可在自訂 Gradle 任務中加入的程式碼。將部分建構邏輯移至任務後,請確保任務只在需要時執行,並可快取結果供後續建構使用,而且這些建構邏輯也符合平行執行的資格 (如果您啟用平行專案執行)。如要進一步瞭解自訂建構邏輯的任務,請參閱官方 Gradle 說明文件。
提示:如果您的建構包含大量自訂工作,建議您建立自訂工作類別來整理 build.gradle
檔案。將類別新增至 project-root/buildSrc/src/main/groovy/
目錄;Gradle 會自動為專案內所有 build.gradle
檔案的類別路徑加入這些類別。
將圖片轉換為 WebP
WebP 是一種圖片檔案格式,可提供有損壓縮 (例如 JPEG) 和透明度 (例如 PNG)。WebP 的壓縮效果比 JPEG 或 PNG 更好。
不需要執行建構時間壓縮,只要縮減圖片檔尺寸,就可以加快建構速度,特別是當應用程式使用大量圖片資源時,更是如此。但是,在解壓 WebP 圖片時,您可能會注意到裝置的 CPU 使用量有些微增加。使用 Android Studio,輕鬆地將圖片轉換為 WebP。
停用 PNG 壓縮功能
如果沒有將 PNG 圖片轉換為 WebP,可以在每次建構應用程式時停用圖片自動壓縮功能,藉此加快建構速度。
如果您使用的是 Android 外掛程式 3.0.0 以上版本,則「偵錯」建構類型會預設停用 PNG 壓縮功能。如要停用其他建構類型的這項最佳化功能,可將以下內容新增到您的 build.gradle
檔案中:
Groovy
android { buildTypes { release { // Disables PNG crunching for the "release" build type. crunchPngs false } } }
Kotlin
android { buildTypes { getByName("release") { // Disables PNG crunching for the "release" build type. isCrunchPngs = false } } }
由於建構類型或變種版本不會定義這個屬性,因此您必須在建構應用程式發布版本時,手動將這個屬性設為「true
」。
使用 JVM 平行垃圾收集器進行實驗
您可以設定 Gradle 使用的最佳 JVM 垃圾收集器,藉此提升建構效能。JDK 8 已預設設定為使用平行垃圾收集器,而 JDK 9 及以上版本則設定為使用 G1 垃圾收集器。
為了提升建構效能,我們建議您使用平行垃圾收集器測試 Gradle 建構。在 gradle.properties
中設定:
org.gradle.jvmargs=-XX:+UseParallelGC
如果該欄位已設有其他選項,則新增一個新選項:
org.gradle.jvmargs=-Xmx1536m -XX:+UseParallelGC
如要使用其他設定測量建構速度,請參閱剖析版本一文。
增加 JVM 堆積大小
如果發現建構速度緩慢,而且在建構分析器結果中,垃圾收集需要超過 15% 的建構時間,則應增加 Java 虛擬機器 (JVM) 堆積大小。在 gradle.properties
檔案中,將限制設定為 4、6 或 8 GB,如以下範例所示:
org.gradle.jvmargs=-Xmx6g
然後測試建構速度改善。如要判斷最佳堆積大小,最簡單的方法是將限制提高一點,然後測試充分建構速度。
如果您同時使用 JVM 平行垃圾收集器,則整行程式碼應如下所示:
org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g
您可以開啟 HeapDumpOnOutOfMemoryError 標記,藉此分析 JVM 記憶體錯誤。如此一來,若記憶體不足,JVM 就會產生記憶體快照資料。
使用非遞移 R 類別
使用非遞移 R
類別,以更快地建構具有多個模組的應用程式。這樣可以確保每個模組的 R
類別只包含其本身資源的參照,而不必提取其依附元件的參照,避免資源重複的情形,進而加快建構速度,同時享有避免編譯帶來的對應好處。這是 Android Gradle 外掛程式 8.0.0 以上版本的預設行為。
從 Android Studio Bumblebee 開始,新專案會預設啟用非遞移 R
類別。對於使用舊版 Android Studio 建立的專案,若要將其更新為使用非遞移 R
類別,請依序前往「Refactor」>「Migrate to Non-Transitive R Classes」。
如要進一步瞭解應用程式資源和 R
類別,請參閱「應用程式資源總覽」一文。
使用非常數 R 類別
在應用程式和測試中使用非常數 R
類別欄位,可提升 Java 編譯作業的成效,進一步提高資源縮減程序的精確度。
對程式庫而言,R
類別欄位一律為非常數,這是因為針對依附於程式庫的應用程式或測試封裝 APK 時,資源會加上編號。這是 Android Gradle 外掛程式 8.0.0 以上版本的預設行為。
停用 Jetifier 旗標
由於大多數專案都直接使用 AndroidX 程式庫,因此您可以移除 Jetifier 旗標以提升建構效能。如要移除 Jetifier 標記,請在 gradle.properties
檔案中設定 android.enableJetifier=false
。
版本分析器可以執行檢查,確認是否可安全移除該標記,確保您的專案能有更佳的建構效能,並從未維護的 Android 支援資料庫中遷移。如要進一步瞭解版本分析器,請參閱「藉助版本分析器排解版本效能問題」一文。
使用設定快取功能 (實驗功能)
「設定快取」屬於實驗功能,可讓 Gradle 記錄建構工作圖表的資訊,並在後續建構作業中重複使用,Gradle 就不必重新設定整個建構作業。
如要啟用設定快取功能,請按照下列步驟操作:
- 確認所有專案外掛程式都相容。
使用版本分析器檢查專案是否與設定快取相容。版本分析器會執行一系列測試版本,判斷是否要為專案啟用這項功能。請參閱問題 #13490,瞭解支援的外掛程式清單。
將下列程式碼新增至
gradle.properties
檔案:org.gradle.unsafe.configuration-cache=true # Use this flag carefully, in case some of the plugins are not fully compatible. org.gradle.unsafe.configuration-cache-problems=warn
啟用設定快取功能後,首次執行專案時,建構作業輸出內容應會顯示 Calculating task graph as no configuration cache is available for tasks
。後續執行時,建構作業輸出內容應顯示 Reusing configuration cache
。
如要進一步瞭解設定快取功能,請參閱網誌文章「Configuration caching deep dive」(設定快取深入解析),以及 Gradle 說明文件「configuration cache」(設定快取)。