提升建構速度

建構時間越長,開發過程就越慢。本頁提供一些技巧 解決建構速度瓶頸

改善應用程式建構速度的一般程序如下:

  1. 利用幾個步驟執行最佳化建構設定,為大多數 Android Studio 專案帶來立竿見影的效果。
  2. 剖析版本,以辨識及診斷 可能會使專案或工作站特有複雜瓶頸

在開發應用程式時,部署至搭載 Android 的裝置 7.0 (API 級別 24) 以上版本。新版 Google Analytics Android 平台能以更好的機制推送更新到應用程式。 例如 Android 執行階段 (ART) 和原生支援多個 DEX 檔案

注意:第一次清理後,您可能會注意到 無論是清理或漸進式建構,執行速度快上許多 本頁介紹的最佳化功能這是因為 Gradle Daemon 有一個增加效能的「暖身」時間,這與其他 JVM 過程類似。

最佳化建構設定

請按照下列提示來提升 Android Studio 專案的建構速度。

確認工具為最新版本

幾乎所有 Android 工具都能實現建構最佳化並收到新功能 每次更新本頁中的某些提示假設您使用的是最新版的軟體 版本。為了充分利用最新的最佳化功能,請確保以下項目為最新版本:

使用 KSP 而非 kapt

Kotlin 註解處理工具 (kapt) 大幅比 Kotlin 慢 符號處理器 (KSP)。如要使用已加註的 Kotlin 來源,並使用 會處理註解 (例如 Room) 建議您遷移至 KSP

避免編譯不必要的資源

請勿編譯及封裝非測試中的資源,例如: 以及支援更多語言本地化和螢幕密度資源只需指定一種 您的「開發人員」的語言資源和螢幕密度變種版本,如以下範例所示:

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()敬上 課程中也會快速介紹 Memorystore 這是 Google Cloud 的全代管 Redis 服務

Gradle 會依照宣告的順序搜尋存放區,因此如果優先列出的存放區含有大部分的外掛程式,建構效能就會有所提升。因此,您可以嘗試使用 gradlePluginPortal() 項目,方法是將該項目放在 settings.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 更好。

不需要執行建構時間壓縮,就能縮減圖片檔尺寸 加快建構速度,尤其是當應用程式使用大量映像檔時 再複習一下,機構節點 是所有 Google Cloud Platform 資源的根節點但是,在解壓 WebP 圖片時,您可能會注意到裝置的 CPU 使用量有些微增加。使用 Android Studio 輕鬆 轉換圖片 轉換為 WebP

停用 PNG 壓縮功能

如未轉換 PNG 檔案 將映像檔傳送至 WebP,您還是可以停用 每次建構應用程式時,系統都會執行圖片壓縮

如果您使用 Android Gradle 外掛程式 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 以上版本 已設為使用

如要提升建構效能,建議您 使用平行處理功能測試 Gradle 建構作業 我們計算了垃圾收集器在 gradle.properties 中設定:

org.gradle.jvmargs=-XX:+UseParallelGC

如果該欄位已設有其他選項,則新增一個新選項:

org.gradle.jvmargs=-Xmx1536m -XX:+UseParallelGC

如要使用其他設定測量建構速度,請參閱 剖析版本

增加 JVM 堆積大小

如果發現建構速度很慢,且尤其是垃圾收集占比 建構時間 版本分析器 結果,請增加 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 >遷移至非遞移 R 類別

如要進一步瞭解應用程式資源和 R 類別,請參閱 應用程式資源總覽

使用非常數 R 類別

使用非常數的 R 類別 應用程式中的欄位和測試中的欄位,可改善 Java 編譯的漸進性 以及更精準的資源縮減R 個類別欄位 對程式庫來說,不一定是常數,因為資源會加上編號 ,以預先封裝依附於該程式庫的應用程式或測試 APK。 這是 Android Gradle 外掛程式 8.0.0 以上版本的預設行為。

停用 Jetifier 旗標

由於大多數專案都直接使用 AndroidX 程式庫,因此您可以移除 Jetifier 旗標,用於提升建構效能。移除 將 Jetifier 旗標設為 android.enableJetifier=false,在您的 gradle.properties 檔案。

版本分析器可以執行檢查,確認旗標是否能 安全移除可讓您的專案,有更好的建構效能,以及從 未經維護的 Android 支援資料庫如要進一步瞭解版本分析器,請參閱 排解建構效能問題

使用設定快取

設定快取 可讓 Gradle 記錄建構工作圖表的資訊,並在後續建構中重複使用,因此 Gradle 不必重新設定整個建構作業。

如要啟用設定快取功能,請按照下列步驟操作:

  1. 確認所有專案外掛程式都相容。

    使用 版本分析器檢查 專案與設定快取相容版本分析器會執行一系列測試 以確定是否可以為專案啟用這項功能。詳情請見 問題 #13490 支援的外掛程式清單

  2. 將下列程式碼新增至 gradle.properties 檔案。

      org.gradle.configuration-cache=true
      # Use this flag carefully, in case some of the plugins are not fully compatible.
      org.gradle.configuration-cache.problems=warn

啟用設定快取功能後,首次執行專案時,建構輸出內容就會 說:Calculating task graph as no configuration cache is available for tasks。過程中 後續執行時,建構輸出內容會顯示 Reusing configuration cache

如要進一步瞭解設定快取功能,請參閱網誌文章 設定快取深入探索 查看 Gradle 說明文件 設定快取

Gradle 8.1 和 Android Gradle 外掛程式 8.1 版造成的設定快取問題

在 Gradle 8.1 版中,設定快取已保持穩定,並導入檔案 API 追蹤。File.exists()File.isDirectory()File.list() 等通話會錄音 Gradle 追蹤設定輸入檔案。

Android Gradle 外掛程式 (AGP) 8.1 會在 Gradle 應處理的部分檔案使用這些 File API 不會視為快取輸入內容如果與以下項目共用快取,則會觸發額外的快取撤銷作業: Gradle 8.1 以上版本,會降低建構效能。 下列項目會在 AGP 8.1 中視為快取輸入內容:

輸入 問題追蹤工具 修正時間:
$GRADLE_USER_HOME/android/FakeDependency.jar 問題 #289232054 AGP 8.2
CMake 輸出 問題 #287676077 AGP 8.2
$GRADLE_USER_HOME/.android/analytics.settings 問題 #278767328 AGP 8.3

如果你使用這些 API 或使用這些 API 的外掛程式, 由於某些使用這些 API 的建構邏輯,建構時間可能會發生迴歸問題 可能會觸發額外的快取撤銷作業請參閱 改善建構設定輸入追蹤 ,進一步瞭解這些模式,以及如何修正建構邏輯,或暫時停用 以及檔案 API 追蹤