Android Gradle 外掛程式 4.0.0 版 (2020 年 4 月)

這個版本的 Android 外掛程式須使用下列項目:

4.0.1 版 (2020 年 7 月)

這個次要更新版本支援與 Android 11 套件瀏覽權限的新預設設定和功能的相容性。

在以前的 Android 版本中,應用程式可以查看裝置已安裝應用程式的完整清單。從 Android 11 (API 級別 30) 開始,應用程式預設只能存取經過篩選的安裝套件清單。現在如果想取得裝置上更完整的應用程式清單,就必須在應用程式或程式庫的 Android 資訊清單中加入 <queries> 元素

Android Gradle 外掛程式 4.1 以上版本與新的 <queries> 宣告相容,但舊版外掛程式並不相容。如果您加入 <queries> 元素,或是開始仰賴支援指定 Android 11 的程式庫或 SDK,可能會在建構應用程式時發生資訊清單合併錯誤。

為解決這項問題,我們針對 AGP 3.3 以上版本推出一組修補程式。如果使用的是舊版 AGP,請升級至以下任一版本:

最低版本 預設版本 附註
Gradle 6.1.1 6.1.1 詳情請參閱「更新 Gradle」一節。
SDK 版本工具 29.0.2 29.0.2 安裝設定 SDK 版本工具。

如要進一步瞭解這項新功能,請參閱「Android 11 套件瀏覽權限」。

新功能

此版本的 Android Gradle 外掛程式內附以下新功能。

支援 Android Studio 版本分析器

「Build Analyzer」視窗有助於瞭解及診斷建構程序相關問題,例如已停用的最佳化功能,以及設定有誤的工作。如果您將 Android Studio 4.0 以上版本與 Android Gradle 外掛程式 4.0.0 以上版本搭配使用,即可使用這項功能。您可以從 Android Studio 開啟「Build Analyzer」視窗,具體方法如下:

  1. 如果尚未建構應用程式,請在選單列中依序選取「Build」>「Make Project」來建構應用程式。
  2. 在選單列中依序選取「View」>「Tool Windows」>「Build」
  3. 在「Build」視窗中,透過以下任一方式開啟「Build Analyzer」視窗:
    • 在 Android Studio 完成專案建構作業後,按一下「Build Analyzer」分頁標籤。
    • 在 Android Studio 完成專案建構作業後,按一下「Build Output」視窗右側的連結。

「Build Analyzer」視窗會在左側以樹狀結構列出可能的建構問題。您可以檢查並點選每個問題,在右側面板中查看詳細資訊。Android Studio 分析建構作業時,會針對決定建構作業時間長度的一組工作進行運算,並以視覺化方式呈現相關資訊,協助您瞭解各項工作的影響。此外,您也可以展開「Warnings」節點,查看警告的詳細資料。

詳情請參閱找出建構速度迴歸的相關內容。

D8 和 R8 中的 Java 8 程式庫脫糖程序

Android Gradle 外掛程式已支援使用多種 Java 8 語言 API,而且對於應用程式的目標 API 級別沒有下限要求。

透過「脫糖」程序,Android Studio 3.0 以上版本的 DEX 編譯器 D8 已支援多種 Java 8 語言功能,例如 lambda 運算式、預設介面方法、試用資源等。Android Studio 4.0 版的脫糖引擎則進一步提供適用於 Java 語言 API 的脫糖程序。也就是說,您現在可以在支援舊版 Android 的應用程式中,加入原先只能在較新 Android 版本中使用的標準語言 API,例如 java.util.streams

這個版本支援以下 API 組合:

  • 依序串流 (java.util.stream)
  • java.time 的子集
  • java.util.function
  • java.util.{Map,Collection,Comparator} 的近期新增項目
  • 選用項目 (java.util.Optionaljava.util.OptionalIntjava.util.OptionalDouble),以及其他適合上述 API 的新類別
  • java.util.concurrent.atomic 的部分新增項目 (AtomicIntegerAtomicLongAtomicReference 上的新方法)
  • ConcurrentHashMap (包含針對 Android 5.0 版的錯誤修正)

為了支援這些語言 API,D8 會編譯獨立的程式庫 DEX 檔案 (其中會導入所缺少 API),並將這個檔案加入應用程式。脫糖程序會重新編寫應用程式程式碼,並在執行階段改為使用這個程式庫。

如要啟用這些語言 API 的支援功能,請在應用程式模組build.gradle 檔案中加入以下程式碼片段:

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled true
  }

compileOptions { // Flag to enable support for the new language APIs coreLibraryDesugaringEnabled true // Sets Java compatibility to Java 8 sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.4' }

android {
  defaultConfig {
    // Required when setting minSdkVersion to 20 or lower
    multiDexEnabled = true
  }

compileOptions { // Flag to enable support for the new language APIs isCoreLibraryDesugaringEnabled = true // Sets Java compatibility to Java 8 sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } }

dependencies { coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.0.4") }

請注意,在下列情況下,您可能也需要在程式庫模組build.gradle 檔案中加入上述程式碼片段:

  • 程式庫模組的檢測設備測試會使用這些語言 API (無論是直接使用,還是透過程式庫模組或其依附元件),藉此提供您的檢測設備測試 APK 所缺少的 API。

  • 您希望單獨在程式庫模組中執行 Lint,以便協助 Lint 識別有效的語言 API 使用情形,避免回報假警告。

新的建構功能啟用/停用選項

Android Gradle 外掛程式 4.0.0 版推出了新的控管方式,可讓您逐一設定建構功能的啟用狀態,例如檢視繫結和資料繫結。這些新增功能預設為停用狀態。透過 buildFeatures 區塊,您可以只啟用所需功能,讓專案達到最佳的建構成效。您可以透過模組層級的 build.gradle 檔案設定每個模組的選項,如下所示:

android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}
android {
  // The default value for each feature is shown below. You can change the value to
  // override the default behavior.
  buildFeatures {
    // Determines whether to generate a BuildConfig class.
    buildConfig = true
    // Determines whether to support View Binding.
    // Note that the viewBinding.enabled property is now deprecated.
    viewBinding = false
    // Determines whether to support Data Binding.
    // Note that the dataBinding.enabled property is now deprecated.
    dataBinding = false
    // Determines whether to generate binder classes for your AIDL files.
    aidl = true
    // Determines whether to support RenderScript.
    renderScript = true
    // Determines whether to support injecting custom variables into the module’s R class.
    resValues = true
    // Determines whether to support shader AOT compilation.
    shaders = true
  }
}

您也可以在專案的 gradle.properties 檔案中加入下列一或多項設定,為專案內的所有模組指定這些功能的預設設定,方法如下所示。請注意,您仍可以使用模組層級 build.gradle 檔案中的 buildFeatures 區塊,覆寫這些專案中通用的預設設定。

android.defaults.buildfeatures.buildconfig=true
android.defaults.buildfeatures.aidl=true
android.defaults.buildfeatures.renderscript=true
android.defaults.buildfeatures.resvalues=true
android.defaults.buildfeatures.shaders=true

功能對功能依附元件

在先前的 Android Gradle 外掛程式版本中,所有功能模組都只能依附應用程式的基本模組。現在使用 Android Gradle 外掛程式 4.0.0 版時,可以加入依附另一個功能模組的功能模組。也就是說,:video 功能可以將依附基本模組的 :camera 功能當做依附元件,如下圖所示。

功能對功能依附元件

功能模組 :video 會將依附基本 :app 模組的 :camera 功能當做依附元件。

這表示當應用程式要求下載某個功能模組時,也會下載該模組依附的其他功能模組。為應用程式建立功能模組後,您可以在這類模組的 build.gradle 檔案中宣告功能對功能的依附元件。比方說,可以宣告 :video 模組依附 :camera,如下所示:

// In the build.gradle file of the ':video' module.
dependencies {
  // All feature modules must declare a dependency
  // on the base module.
  implementation project(':app')
  // Declares that this module also depends on the 'camera'
  // feature module.
  implementation project(':camera')
  ...
}
// In the build.gradle file of the ':video' module.
dependencies {
    // All feature modules must declare a dependency
    // on the base module.
    implementation(project(":app"))
    // Declares that this module also depends on the 'camera'
    // feature module.
    implementation(project(":camera"))
    ...
}

此外,您應該在 Android Studio 中啟用「功能對功能依附元件」的功能,這對於編輯執行設定等作業很有幫助。啟用方法是從選單列依序點選「Help」>「Edit Custom VM Options」,並加入以下內容:

-Drundebug.feature.on.feature=true

依附元件中繼資料

使用 Android Gradle 外掛程式 4.0.0 以上版本建構應用程式時,外掛程式會加入中繼資料,藉此描述編譯至應用程式中的依附元件。在應用程式上傳期間,Play 管理中心會檢查這些中繼資料,讓您享有以下好處:

  • 接收快訊,瞭解應用程式所用 SDK 和依附元件的已知問題
  • 獲得能夠解決這些問題的實用建議

這些資料會經過壓縮、由 Google Play 簽署金鑰加密,並儲存在所發布應用程式的簽署區塊。不過,您可以前往以下目錄,在本機中繼建構檔案中自行檢查相關中繼資料:<project>/<module>/build/outputs/sdk-dependencies/release/sdkDependency.txt

如果不想提供這項資訊,可以在模組的 build.gradle 檔案中加入以下內容,選擇不採用這項機制:

android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}
android {
  dependenciesInfo {
      // Disables dependency metadata when building APKs.
      includeInApk = false
      // Disables dependency metadata when building Android App Bundles.
      includeInBundle = false
  }
}

從 AAR 依附元件匯入原生程式庫

您現在可以從應用程式的 AAR 依附元件匯入 C/C++ 程式庫。只要執行下文的設定步驟,Gradle 就會自動將這些原生程式庫提供給您的外部原生建構系統使用,例如 CMake。請注意,Gradle 只會將這些程式庫提供給建構作業使用,您還是必須設定建構指令碼,才能使用這些程式庫。

系統會以 Prefab 套件格式匯出程式庫。

每個依附元件最多可以揭露一個 Prefab 套件,其中可包含一或多個模組。Prefab 模組是單一程式庫,可以是共用、靜態或僅限標頭的程式庫。

一般來說,套件名稱會與 Maven 成果名稱相同,模組名稱則會與程式庫名稱相同,但並非一定如此。由於您需要知道程式庫的套件和模組名稱,因此可能必須參閱依附元件的說明文件來確定這些名稱。

設定外部原生建構系統

如要查看必須執行的步驟,請根據要使用的外部原生建構系統,按照以下步驟操作。

所有內含原生程式碼的應用程式 AAR 依附元件都會揭露一個 Android.mk 檔案,您需要將此檔案匯入 ndk-build 專案。您可以用 import&endash;module 指令匯入檔案,這種方式會使用 ndk-build 專案的 import&endash;add&endash;path 屬性搜尋您指定的路徑。舉例來說,假如應用程式定義了 libapp.so 並使用 curl,您應該在 Android.mk 檔案中加入以下內容:

  1. 針對 CMake:

    add_library(app SHARED app.cpp)

    # Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

  2. 針對 ndk-build

    include $(CLEAR_VARS)
    LOCAL_MODULE := libapp
    LOCAL_SRC_FILES := app.cpp
    # Link libcurl from the curl AAR.
    LOCAL_SHARED_LIBRARIES := curl
    include $(BUILD_SHARED_LIBRARY)

    # If you don't expect that your project will be built using versions of the NDK # older than r21, you can omit this block. ifneq ($(call ndk-major-at-least,21),true) $(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH)) endif

    # Import all modules that are included in the curl AAR. $(call import-module,prefab/curl)

您的 CMake 專案會透過 CMAKE_FIND_ROOT_PATH 變數,揭露 AAR 包含的原生依附元件。叫用 CMake 時,Gradle 會自動設定這個值,因此如果您的建構系統會修改這個變數,請務必採取附加的做法,不要使用指派的方式。

每個依附元件都會向 CMake 建構作業揭露設定檔套件,您可以使用 find_package 指令匯入該設定檔套件。這個指令會搜尋與指定套件名稱及版本相符的設定檔套件,並揭露該套件所定義的目標,以便用於建構作業。舉例來說,假如應用程式定義了 libapp.so 並使用 curl,您應該在 CMakeLists.txt 檔案中加入以下內容:


add_library(app SHARED app.cpp)

# Add these two lines. find_package(curl REQUIRED CONFIG) target_link_libraries(app curl::curl)

您現在可以在 app.cpp 中指定 #include "curl/curl.h"。建構專案時,您的外部原生建構系統會自動將 libapp.so 連結至 libcurl.so,並將 libcurl.so 封裝至 APK 或應用程式套件。詳情請參閱相關 curl prefab 範例

行為變更

使用這個外掛程式版本時,可能會遇到下列行為變更。

v1/v2 簽署設定更新項目

signingConfig 區塊中的應用程式簽署設定行為已變更如下:

v1 簽署

  • 如果已明確啟用 v1SigningEnabled,AGP 會執行 v1 應用程式簽署。
  • 如果使用者已明確停用 v1SigningEnabled,系統不會執行 v1 應用程式簽署。
  • 如果使用者未明確啟用 v1 簽署,則可根據 minSdktargetSdk 自動停用。

v2 簽署

  • 如果已明確啟用 v2SigningEnabled,AGP 會執行 v2 應用程式簽署。
  • 如果使用者已明確停用 v2SigningEnabled,系統不會執行 v2 應用程式簽署。
  • 如果使用者未明確啟用 v2 簽署,則可根據 targetSdk 自動停用。

經過這些調整後,AGP 就能根據使用者是否已明確啟用相關旗標來停用簽署機制,將建構作業最佳化。在過往版本中,即使 v1Signing 已明確啟用,仍可能遭到停用,讓使用者感到不解。

移除 featureinstantapp Android Gradle 外掛程式

Android Gradle 外掛程式 3.6.0 版淘汰了功能外掛程式 (com.android.feature) 和免安裝應用程式外掛程式 (com.android.instantapp),並改用動態功能外掛程式 (com.android.dynamic-feature),可讓您以 Android App Bundle 格式建構及封裝免安裝應用程式。

Android Gradle 外掛程式 4.0.0 以上版本會完全移除這些淘汰的外掛程式。因此,如要使用最新版的 Android Gradle 外掛程式,就必須遷移您的免安裝應用程式,改為支援 Android App Bundle。遷移免安裝應用程式後,您就能發揮應用程式套件的優勢,並簡化應用程式的模組設計

注意:如要在 Android Studio 4.0 以上版本中開啟使用已移除外掛程式的專案,該專案必須採用 Android Gradle 外掛程式 3.6.0 以下版本。

移除註解處理程序分割功能

我們移除了將註解處理程序分割成專屬工作的功能。這個選項可在僅限 Java 的專案中使用非漸進式註解處理工具時,用來維持漸進式的 Java 編譯作業。啟用方式為在 gradle.properties 檔案中,將 android.enableSeparateAnnotationProcessing 設為 true,但這個方法現已無效。

如要改善建構效能,您應改成使用漸進式註解處理工具

淘汰 includeCompileClasspath

Android Gradle 外掛程式不會再檢查或納入您在編譯類別路徑中宣告的註解處理工具,annotationProcessorOptions.includeCompileClasspath DSL 屬性也已無法運作。如果您在編譯類別路徑中加入註解處理工具,可能會看到下列錯誤:

Error: Annotation processors must be explicitly declared now.

為解決此問題,您必須使用 annotationProcessor 依附元件設定,在 build.gradle 檔案中加入註解處理工具。詳情請參閱「新增註解處理工具」。

自動封裝 CMake 使用的預先建構依附元件

過往的 Android Gradle 外掛程式版本必須使用 jniLibs 明確封裝 CMake 外部原生建構作業使用的預先建構程式庫。在模組的 src/main/jniLibs 目錄或 build.gradle 檔案所設定的其他目錄中,可能已有程式庫:

sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.srcDirs = ['libs']
  }
}
sourceSets {
  main {
    // The libs directory contains prebuilt libraries that are used by the
    // app's library defined in CMakeLists.txt via an IMPORTED target.
    jniLibs.setSrcDirs(listOf("libs"))
  }
}

Android Gradle 外掛程式 4.0 版已不再需要以上設定,而且這些設定會導致建構作業失敗:

* What went wrong:
Execution failed for task ':app:mergeDebugNativeLibs'.
  > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
    > More than one file was found with OS independent path 'lib/x86/libprebuilt.so'

外部原生建構作業現在會自動封裝程式庫,因此使用 jniLibs 明確封裝程式庫會造成重複作業。如要避免發生建構錯誤,請將預先建構程式庫移到 jniLibs 以外的位置,或者從 build.gradle 檔案中移除 jniLibs 設定。

已知問題

本節說明 Android Gradle 外掛程式 4.0.0 的已知問題。

Gradle 工作站機制中的競爭狀況

&endash;&endash;no&endash;daemon 與 Gradle 6.3 以下版本一起執行時,Android Gradle 外掛程式 4.0 版的異動可能在 Gradle 中觸發競爭狀況,造成建構作業在完成後停止運作。

Gradle 6.4 版會修正這項問題。