Android 規則

規則

android_binary

查看規則來源
android_binary(name, deps, srcs, assets, assets_dir, compatible_with, crunch_png, custom_package, debug_key, debug_signing_keys, debug_signing_lineage_file, densities, deprecation, dex_shards, dexopts, distribs, enable_data_binding, exec_compatible_with, exec_properties, features, incremental_dexing, instruments, javacopts, key_rotation_min_sdk, licenses, main_dex_list, main_dex_list_opts, main_dex_proguard_specs, manifest, manifest_values, multidex, nocompress_extensions, package_id, plugins, proguard_apply_dictionary, proguard_apply_mapping, proguard_generate_mapping, proguard_specs, resource_configuration_filters, resource_files, restricted_to, shrink_resources, tags, target_compatible_with, testonly, visibility)

產生 Android 應用程式套件檔案 (.apk)。

隱含輸出目標

  • name.apk:以偵錯金鑰簽署並完成 zipaligned 的 Android 應用程式套件檔案,可用於開發及偵錯應用程式。使用偵錯金鑰簽署應用程式時,無法發布應用程式。
  • name_unsigned.apk:上述檔案的未簽署版本,可使用發布金鑰簽署,然後向大眾發布。
  • name_deploy.jar:包含這個目標的轉換閉包的 Java 封存檔。

    部署 JAR 包含所有類別,這些類別會由從頭到尾搜尋這個目標的執行階段類別路徑的類別載入器找到。

  • name_proguard.jar:Java 封存檔,內含在 name_deploy.jar 上執行 ProGuard 的結果。只有在指定 proguard_specs 屬性時,才會產生這項輸出內容。
  • name_proguard.map:在 name_deploy.jar 上執行 ProGuard 後產生的對應檔。只有在指定 proguard_specs 屬性,並設定 proguard_generate_mappingshrink_resources 時,才會產生這項輸出內容。

範例

您可以在 Bazel 原始碼樹的 examples/android 目錄中找到 Android 規則範例。

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

deps

標籤清單;預設值為 []

要連結至二進位目標的其他程式庫清單。 允許的程式庫類型包括:android_libraryjava_library (含 android 限制) 和 cc_library,可包裝或產生 Android 目標平台的 .so 原生程式庫。
srcs

標籤清單;預設值為 []

系統會處理來源檔案清單,然後建立目標。

已編譯類型為「.java」的「srcs」檔案。 為了方便閱讀,請勿將產生的 .java 來源檔案名稱放入 srcs。請改為將依附規則名稱放在 srcs 中,如下所述。

系統會解壓縮並編譯 .srcjar 類型的 srcs 檔案。(如果您需要使用 genrule 或建構擴充功能產生一組 .java 檔案,這項功能就非常實用)。

assets

標籤清單;預設值為 []

要封裝的資產清單。 這通常是 assets 目錄下所有檔案的 glob。您也可以參照其他規則 (產生檔案的任何規則) 或其他套件中匯出的檔案,前提是所有這些檔案都位於相應套件的 assets_dir 目錄下。
assets_dir

字串;預設值為 ""

這個字串會提供 assets 中檔案的路徑。 assetsassets_dir 這兩個屬性用來描述封裝資產,且必須同時提供或都不提供。
crunch_png

布林值;預設值為 True

是否要壓縮 PNG 檔案。這與九宮格處理程序無關,因為九宮格處理程序一律會執行。這是已淘汰的解決方法,用來解決 aapt 錯誤,該錯誤已在 aapt2 中修正。
custom_package

字串;預設值為 ""

要產生 Java 來源的 Java 套件。 根據預設,套件會從包含規則的 BUILD 檔案所在目錄推斷而來。您可以指定其他套件,但強烈建議不要這麼做,因為這可能會導致類別路徑與其他程式庫發生衝突,而這類衝突只會在執行階段偵測到。
debug_key

標籤;預設值為 "@bazel_tools//tools/android:debug_keystore"

包含偵錯 KeyStore 的檔案,用於簽署偵錯 APK。您通常不會想使用預設金鑰以外的金鑰,因此應省略這個屬性。

警告:請勿使用正式版金鑰,這類金鑰應嚴格保管,且不應存放在來源樹狀結構中

debug_signing_keys

標籤清單;預設值為 []

檔案清單,用來簽署偵錯 APK 的偵錯 KeyStore。通常您不會想使用預設金鑰以外的金鑰,因此應省略這個屬性。

警告:請勿使用正式版金鑰,這類金鑰應嚴格保管,且不應存放在來源樹狀結構中

debug_signing_lineage_file

標籤;預設值為 None

包含 debug_signing_keys 簽署沿革的檔案。通常您不會想使用預設金鑰以外的金鑰,因此應省略這個屬性。

警告:請勿使用正式版金鑰,這類金鑰應嚴格保管,且不應存放在來源樹狀結構中

densities

字串清單;預設值為 []

建構 APK 時要篩選的密度。這樣一來,系統就會移除不會由指定螢幕密度的裝置載入的點陣可繪資源,進而縮減 APK 大小。如果資訊清單尚未包含超集清單,系統也會在資訊清單中新增對應的「compatible-screens」部分。
dex_shards

整數;預設值為 1

應分解為的 Dexing 分片數量。 這樣做會大幅加快 dexing 速度,但會增加應用程式安裝和啟動時間。二進位檔越大,應使用的分片就越多。建議您先從 25 開始實驗。

請注意,每個分片都會在最終應用程式中產生至少一個 DEX。因此,建議不要將此值設為 1 以上,以免發布二進位檔。

dexopts

字串清單;預設值為 []

產生 classes.dex 時,dx 工具的額外指令列標記。 須遵守「製作變數」替代和 Bourne Shell 權杖化
enable_data_binding

布林值;預設值為 False

如果是 true,這項規則會處理透過 resource_files 屬性納入的版面配置資源中的資料繫結運算式。如果沒有這項設定,資料繫結運算式會導致建構失敗。

如要使用資料繫結建構 Android 應用程式,您也必須執行下列操作:

  1. 請為所有以遞移方式依附於這項規則的 Android 規則設定這項屬性。 這是因為依附元件會透過資源合併,繼承規則的資料繫結運算式。因此,他們也需要使用資料繫結建構,才能剖析這些運算式。
  2. 為設定這個屬性的所有目標新增資料繫結執行階段程式庫的 deps = 項目。這個程式庫的位置取決於你的倉庫設定。
incremental_dexing

整數;無法設定;預設值為 -1

強制目標建構時是否要使用遞增式 Dexing,覆寫預設值和 --incremental_dexing 旗標。
instruments

標籤;預設值為 None

要插碼的android_binary目標。

如果設定了這項屬性,這個 android_binary 會視為檢測設備測試的測試應用程式。android_instrumentation_test 目標隨後可以在 test_app 屬性中指定這個目標。

javacopts

字串清單;預設值為 []

這個目標的額外編譯器選項。 須遵守「製作變數」替代和 Bourne Shell 權杖化

這些編譯器選項會在全域編譯器選項之後傳遞至 javac。

key_rotation_min_sdk

字串;預設值為 ""

設定 APK 輪替簽署金鑰應使用的最低 Android 平台版本 (API 級別),以產生 APK 簽名。APK 的原始簽署金鑰將會用於所有舊平台版本。
main_dex_list

標籤;預設值為 None

文字檔案包含類別檔案名稱清單。這些類別檔案定義的類別會放在主要 classes.dex 中,例如:
          android/support/multidex/MultiDex$V19.class
          android/support/multidex/MultiDex.class
          android/support/multidex/MultiDexApplication.class
          com/google/common/base/Objects.class
                    
必須與 multidex="manual_main_dex" 一併使用。
main_dex_list_opts

字串清單;預設值為 []

要傳遞至主要 DEX 清單建構工具的指令列選項。 使用這個選項可影響主要 dex 清單中包含的類別。
main_dex_proguard_specs

標籤清單;預設值為 []

要用做 Proguard 規格的檔案,用於判斷必須保留在主要 DEX 中的類別。只有在 multidex 屬性設為 legacy 時,才能使用這項屬性。
manifest

標籤 (必填)

Android 資訊清單檔案的名稱,通常為 AndroidManifest.xml。 如果定義 resource_files 或 assets,則必須定義。
manifest_values

字典:字串 -> 字串;預設值為 {}

要在資訊清單中覆寫的值字典。

資訊清單中的所有 ${name} 執行個體,都會替換為這個字典中與名稱對應的值。

applicationIdversionCodeversionNameminSdkVersiontargetSdkVersionmaxSdkVersion 也會覆寫資訊清單和 uses-sdk 標記中的對應屬性。

系統會忽略 packageName,並從 applicationId (如有指定) 或資訊清單中的套件設定 packageName

如果將 manifest_merger 設為 legacy,只有 applicationIdversionCodeversionName 會生效。

multidex

字串;預設值為 "native"

是否要將程式碼分割成多個 DEX 檔案。
可能的值包括:
  • native:如果超過 DEX 64K 索引限制,請將程式碼分割成多個 DEX 檔案。假設平台原生支援在執行階段載入 multidex 類別。 這項功能僅適用於 Android L 以上版本
  • legacy:如果超過 DEX 64K 索引限制,請將程式碼分割成多個 DEX 檔案。假設多重索引類別是透過應用程式碼載入 (即沒有原生平台支援)。
  • manual_main_dex:如果超出 DEX 64K 索引限制,請將程式碼分割成多個 DEX 檔案。您必須使用 main_dex_list 屬性,在文字檔中提供類別清單,指定主要 DEX 檔案的內容。
  • off:將所有程式碼編譯為單一 DEX 檔案,即使超出索引限制也沒關係。
nocompress_extensions

字串清單;預設值為 []

要在 APK 中保留未壓縮狀態的副檔名清單。
package_id

整數;預設值為 0

要指派給這個二進位檔中資源的套件 ID。

詳情請參閱 AAPT2 的 --package-id 引數。通常可以 (也應該) 保留未設定的狀態,這樣就會採用預設值 127 (0x7F)。

plugins

標籤清單;預設值為 []

在編譯時執行的 Java 編譯器外掛程式。每當建構這個目標時,系統都會執行外掛程式屬性中指定的每個 java_plugin。外掛程式產生的資源會納入目標的結果 JAR 中。
proguard_apply_dictionary

標籤;預設值為 None

用來做為 ProGuard 對應的檔案。 以換行符分隔的「字詞」檔案,可在混淆處理期間重新命名類別和成員時從中提取字詞。
proguard_apply_mapping

標籤;預設值為 None

用來做為 ProGuard 對應的檔案。 由 proguard_generate_mapping 產生的對應檔,可重複使用,將相同對應套用至新版本。
proguard_generate_mapping

布林值;無法設定;預設值為 False

是否要產生 Proguard 對應檔。 只有在指定 proguard_specs 時,系統才會產生對應檔案。這個檔案會列出原始和經過模糊處理的類別、方法和欄位名稱之間的對應關係。

警告:如果使用這項屬性,Proguard 規格不得包含 -dontobfuscate-printmapping

proguard_specs

標籤清單;預設值為 []

用來做為 Proguard 規格的檔案。 這個檔案會說明 Proguard 要使用的一組規格。
resource_configuration_filters

字串清單;預設值為 []

資源設定篩選器清單,例如「en」,可將 APK 中的資源限制為僅包含「en」設定中的資源。如要啟用偽本地化,請加入 en_XA 和/或 ar_XB 偽本地化設定。
resource_files

標籤清單;預設值為 []

要封裝的資源清單。 這通常是 res 目錄下所有檔案的 glob
產生的檔案 (來自 genrules) 也可以在此處透過標籤參照。唯一限制是產生的輸出內容必須與任何其他納入的資源檔案位於相同的「res」目錄下。
shrink_resources

整數;預設值為 -1

是否要執行資源縮減。系統會從 APK 中移除二進位檔未使用的資源。這項功能僅適用於使用本機資源的規則 (即 manifestresource_files 屬性),且需要 ProGuard。運作方式與 Gradle 資源縮減器 (https://developer.android.com/studio/build/shrink-code.html#shrink-resources) 大致相同。

重要差異:

  • values/ 中的資源和以檔案為基礎的資源都會一併移除
  • 預設使用 strict mode
  • 只有 aapt2 支援移除未使用的 ID 資源
如果啟用資源縮減功能,系統也會產生 name_files/resource_shrinker.log,詳細說明執行的分析和刪除作業。

可能的值:

  • shrink_resources = 1:開啟 Android 資源縮減功能
  • shrink_resources = 0:關閉 Android 資源縮減功能
  • shrink_resources = -1:縮減作業由 --android_resource_shrinking 標記控制。

aar_import

查看規則來源
aar_import(name, deps, data, aar, compatible_with, deprecation, distribs, exec_compatible_with, exec_properties, exports, features, licenses, restricted_to, srcjar, tags, target_compatible_with, testonly, visibility)

這項規則允許使用 .aar 檔案做為 android_libraryandroid_binary 規則的程式庫。

範例

    aar_import(
        name = "google-vr-sdk",
        aar = "gvr-android-sdk/libraries/sdk-common-1.10.0.aar",
    )

    android_binary(
        name = "app",
        manifest = "AndroidManifest.xml",
        srcs = glob(["**.java"]),
        deps = [":google-vr-sdk"],
    )

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

aar

標籤 (必填)

要提供給依附於這個目標的 Android 目標的 .aar 檔案。
exports

標籤清單;預設值為 []

要匯出至依據這項規則的規則的目標。 請參閱 java_library.exports。
srcjar

標籤;預設值為 None

包含 AAR 中已編譯 JAR 檔案的原始碼。

android_library

查看規則來源
android_library(name, deps, srcs, data, assets, assets_dir, compatible_with, custom_package, deprecation, distribs, enable_data_binding, exec_compatible_with, exec_properties, exported_plugins, exports, exports_manifest, features, idl_import_root, idl_parcelables, idl_preprocessed, idl_srcs, javacopts, licenses, manifest, neverlink, plugins, proguard_specs, resource_files, restricted_to, tags, target_compatible_with, testonly, visibility)

這項規則會將來源編譯並封存至 .jar 檔案。 Android 執行階段程式庫 android.jar 會隱含地放在編譯類別路徑上。

隱含輸出目標

  • libname.jar:Java 封存檔。
  • libname-src.jar:包含來源 (「來源 JAR」) 的封存檔。
  • name.aar:Android「aar」套件,內含這個目標的 Java 封存檔和資源。不含遞移閉包。

範例

您可以在 Bazel 原始碼樹的 examples/android 目錄中找到 Android 規則範例。

以下範例說明如何設定 idl_import_root。讓 //java/bazel/helloandroid/BUILD 包含:

android_library(
    name = "parcelable",
    srcs = ["MyParcelable.java"], # bazel.helloandroid.MyParcelable

    # MyParcelable.aidl will be used as import for other .aidl
    # files that depend on it, but will not be compiled.
    idl_parcelables = ["MyParcelable.aidl"] # bazel.helloandroid.MyParcelable

    # We don't need to specify idl_import_root since the aidl file
    # which declares bazel.helloandroid.MyParcelable
    # is present at java/bazel/helloandroid/MyParcelable.aidl
    # underneath a java root (java/).
)

android_library(
    name = "foreign_parcelable",
    srcs = ["src/android/helloandroid/OtherParcelable.java"], # android.helloandroid.OtherParcelable
    idl_parcelables = [
        "src/android/helloandroid/OtherParcelable.aidl" # android.helloandroid.OtherParcelable
    ],

    # We need to specify idl_import_root because the aidl file which
    # declares android.helloandroid.OtherParcelable is not positioned
    # at android/helloandroid/OtherParcelable.aidl under a normal java root.
    # Setting idl_import_root to "src" in //java/bazel/helloandroid
    # adds java/bazel/helloandroid/src to the list of roots
    # the aidl compiler will search for imported types.
    idl_import_root = "src",
)

# Here, OtherInterface.aidl has an "import android.helloandroid.CallbackInterface;" statement.
android_library(
    name = "foreign_interface",
    idl_srcs = [
        "src/android/helloandroid/OtherInterface.aidl" # android.helloandroid.OtherInterface
        "src/android/helloandroid/CallbackInterface.aidl" # android.helloandroid.CallbackInterface
    ],

    # As above, idl_srcs which are not correctly positioned under a java root
    # must have idl_import_root set. Otherwise, OtherInterface (or any other
    # interface in a library which depends on this one) will not be able
    # to find CallbackInterface when it is imported.
    idl_import_root = "src",
)

# MyParcelable.aidl is imported by MyInterface.aidl, so the generated
# MyInterface.java requires MyParcelable.class at compile time.
# Depending on :parcelable ensures that aidl compilation of MyInterface.aidl
# specifies the correct import roots and can access MyParcelable.aidl, and
# makes MyParcelable.class available to Java compilation of MyInterface.java
# as usual.
android_library(
    name = "idl",
    idl_srcs = ["MyInterface.aidl"],
    deps = [":parcelable"],
)

# Here, ServiceParcelable uses and thus depends on ParcelableService,
# when it's compiled, but ParcelableService also uses ServiceParcelable,
# which creates a circular dependency.
# As a result, these files must be compiled together, in the same android_library.
android_library(
    name = "circular_dependencies",
    srcs = ["ServiceParcelable.java"],
    idl_srcs = ["ParcelableService.aidl"],
    idl_parcelables = ["ServiceParcelable.aidl"],
)

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

deps

標籤清單;預設值為 []

要連結的其他程式庫清單。 允許的程式庫類型包括:android_libraryjava_library (含 android 限制) 和 cc_library,可包裝或產生 Android 目標平台的 .so 原生程式庫。
srcs

標籤清單;預設值為 []

系統會處理 .java.srcjar 檔案清單,以建立目標。

已編譯類型為「.java」的「srcs」檔案。 為了方便閱讀,請勿將產生的 .java 來源檔案名稱放入 srcs。請改為將依附規則名稱放在 srcs 中,如下所述。

系統會解壓縮並編譯 .srcjar 類型的 srcs 檔案。(如果您需要使用 genrule 或建構擴充功能產生一組 .java 檔案,這項功能就非常實用)。

如果省略 srcs,系統會從這項規則匯出 deps 中指定的任何依附元件 (如要進一步瞭解如何匯出依附元件,請參閱 java_library 的匯出項目)。不過,這項行為即將淘汰,請盡量不要依賴這項行為。

assets

標籤清單;預設值為 []

要封裝的資產清單。 這通常是 assets 目錄下所有檔案的 glob。您也可以參照其他規則 (產生檔案的任何規則) 或其他套件中匯出的檔案,前提是所有這些檔案都位於相應套件的 assets_dir 目錄下。
assets_dir

字串;預設值為 ""

這個字串會提供 assets 中檔案的路徑。 assetsassets_dir 這兩個屬性用來描述封裝資產,且必須同時提供或都不提供。
custom_package

字串;預設值為 ""

要產生 Java 來源的 Java 套件。 根據預設,套件會從包含規則的 BUILD 檔案所在目錄推斷而來。您可以指定其他套件,但強烈建議不要這麼做,因為這可能會導致類別路徑與其他程式庫發生衝突,而這類衝突只會在執行階段偵測到。
enable_data_binding

布林值;預設值為 False

如果是 true,這項規則會處理透過 resource_files 屬性納入的版面配置資源中的資料繫結運算式。如果沒有這項設定,資料繫結運算式會導致建構失敗。

如要使用資料繫結建構 Android 應用程式,您也必須執行下列操作:

  1. 請為所有以遞移方式依附於這項規則的 Android 規則設定這項屬性。 這是因為依附元件會透過資源合併,繼承規則的資料繫結運算式。因此,他們也需要使用資料繫結建構,才能剖析這些運算式。
  2. 為設定這個屬性的所有目標新增資料繫結執行階段程式庫的 deps = 項目。這個程式庫的位置取決於你的倉庫設定。
exported_plugins

標籤清單;預設值為 []

要匯出至直接依附於這個程式庫的程式庫的 java_plugin 清單 (例如註解處理器)。

指定的 java_plugin 清單會套用至直接依附這個程式庫的任何程式庫,就像該程式庫已在 plugins 中明確宣告這些標籤一樣。

exports

標籤清單;預設值為 []

透過 exports 屬性到達的所有規則的閉包,都會視為直接依附於目標的任何規則的直接依附元件 (目標具有 exports)。

exports 不是所屬規則的直接依附元件。

exports_manifest

整數;預設值為 1

是否要將資訊清單項目匯出至依附於這個目標的 android_binary 目標。uses-permissions 屬性一律不會匯出。
idl_import_root

字串;預設值為 ""

包含這個程式庫中 IDL 來源的 Java 套件樹狀結構根目錄的套件相對路徑。

處理依附於這個程式庫的 IDL 來源時,系統會將這個路徑做為匯入根目錄。

指定 idl_import_root 時,idl_parcelablesidl_srcs 都必須位於 idl_import_root 下,且路徑是由所代表物件的 Java 套件指定。如未指定 idl_import_rootidl_parcelablesidl_srcs 都必須位於 Java 根目錄下,由其套件指定的路徑。

請參閱 範例

idl_parcelables

標籤清單;預設值為 []

要以匯入項目提供的 Android IDL 定義清單。 這些檔案會以匯入形式提供給依附於這個程式庫的任何android_library目標 (直接或透過其遞移閉包),但不會翻譯成 Java 或編譯。

這個程式庫中只能包含直接對應至 .java 來源的 .aidl 檔案 (例如 Parcelable 的自訂實作),否則應使用 idl_srcs

這些檔案必須放置在適當位置,aidl 編譯器才能找到。 如要瞭解這項設定的意義,請參閱 idl_import_root 的說明

idl_preprocessed

標籤清單;預設值為 []

要以匯入形式提供的預先處理 Android IDL 定義清單。 這些檔案會以匯入形式提供給依附於這個程式庫的任何android_library目標 (直接或透過其遞移閉包),但不會翻譯成 Java 或編譯。

只能加入與這個程式庫中 .java 來源直接對應的預先處理 .aidl 檔案 (例如 Parcelable 的自訂實作),否則請使用 idl_srcs 處理需要轉換為 Java 介面的 Android IDL 定義,並使用 idl_parcelable 處理未預先處理的 AIDL 檔案。

idl_srcs

標籤清單;預設值為 []

要轉換為 Java 介面的 Android IDL 定義清單。 Java 介面產生後,會與 srcs 的內容一起編譯。

這些檔案會以匯入的形式提供給任何依附於這個程式庫的 android_library 目標 (直接或透過其遞移閉包)。

這些檔案必須放置在適當位置,aidl 編譯器才能找到。 如要瞭解這項設定的意義,請參閱 idl_import_root 的說明

javacopts

字串清單;預設值為 []

這個目標的額外編譯器選項。 須遵守「製作變數」替代和 Bourne Shell 權杖化

這些編譯器選項會在全域編譯器選項之後傳遞至 javac。

manifest

標籤;預設值為 None

Android 資訊清單檔案的名稱,通常為 AndroidManifest.xml。 如果定義 resource_files 或 assets,則必須定義。

布林值;預設值為 False

這個程式庫只能用於編譯,不能在執行階段使用。 系統不會在 .apk 建立作業中使用標示為 neverlink 的規則輸出內容。如果程式庫會在執行期間由執行階段環境提供,這個選項就非常實用。
plugins

標籤清單;預設值為 []

在編譯時執行的 Java 編譯器外掛程式。每當建構這個目標時,系統都會執行外掛程式屬性中指定的每個 java_plugin。外掛程式產生的資源會納入目標的結果 JAR 中。
proguard_specs

標籤清單;預設值為 []

用來做為 Proguard 規格的檔案。 這些檔案會說明 Proguard 要使用的規格集。如果指定,系統會將這些項目加入依附於這個程式庫的任何 android_binary 目標。這裡包含的檔案只能有等冪規則,也就是 -dontnote、-dontwarn、assumenosideeffects,以及以 -keep 開頭的規則。其他選項只能顯示在 android_binary 的 proguard_specs 中,確保合併作業不會出現同義反覆的情況。
resource_files

標籤清單;預設值為 []

要封裝的資源清單。 這通常是 res 目錄下所有檔案的 glob
產生的檔案 (來自 genrules) 也可以在此處透過標籤參照。唯一限制是產生的輸出內容必須與任何其他納入的資源檔案位於相同的「res」目錄下。

android_instrumentation_test

查看規則來源
android_instrumentation_test(name, data, args, compatible_with, deprecation, distribs, env, env_inherit, exec_compatible_with, exec_properties, features, flaky, licenses, local, restricted_to, shard_count, size, support_apks, tags, target_compatible_with, target_device, test_app, testonly, timeout, toolchains, visibility)

android_instrumentation_test 規則會執行 Android 檢測設備測試。這會啟動模擬器、安裝受測應用程式、測試應用程式和任何其他必要應用程式,並執行測試套件中定義的測試。

test_app 屬性會指定包含測試的 android_binary。這個 android_binary 會透過 instruments 屬性,指定受測的 android_binary 應用程式。

範例

# java/com/samples/hello_world/BUILD

android_library(
    name = "hello_world_lib",
    srcs = ["Lib.java"],
    manifest = "LibraryManifest.xml",
    resource_files = glob(["res/**"]),
)

# The app under test
android_binary(
    name = "hello_world_app",
    manifest = "AndroidManifest.xml",
    deps = [":hello_world_lib"],
)
# javatests/com/samples/hello_world/BUILD

android_library(
    name = "hello_world_test_lib",
    srcs = ["Tests.java"],
    deps = [
      "//java/com/samples/hello_world:hello_world_lib",
      ...  # test dependencies such as Espresso and Mockito
    ],
)

# The test app
android_binary(
    name = "hello_world_test_app",
    instruments = "//java/com/samples/hello_world:hello_world_app",
    manifest = "AndroidManifest.xml",
    deps = [":hello_world_test_lib"],
)

android_instrumentation_test(
    name = "hello_world_uiinstrumentation_tests",
    target_device = ":some_target_device",
    test_app = ":hello_world_test_app",
)

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

support_apks

標籤清單;預設值為 []

在檢測設備測試開始前,要在裝置上安裝的其他 APK。
target_device

標籤 (必填)

測試應執行的 android_device

如要在已執行的模擬器或實體裝置上執行測試,請使用下列引數: --test_output=streamed --test_arg=--device_broker_type=LOCAL_ADB_SERVER --test_arg=--device_serial_number=$device_identifier

test_app

標籤 (必填)

包含測試類別的 android_binary 目標。 android_binary 目標必須透過 instruments 屬性指定要測試的目標。

android_local_test

查看規則來源
android_local_test(name, deps, srcs, data, args, compatible_with, custom_package, densities, deprecation, enable_data_binding, env, env_inherit, exec_compatible_with, exec_properties, features, flaky, javacopts, jvm_flags, licenses, local, manifest, manifest_values, nocompress_extensions, plugins, resource_configuration_filters, resource_jars, resource_strip_prefix, restricted_to, runtime_deps, shard_count, size, stamp, tags, target_compatible_with, test_class, testonly, timeout, toolchains, use_launcher, visibility)

這項規則適用於在本機進行單元測試 android_library 規則 (而非在裝置上)。可搭配 Android Robolectric 測試架構使用。 如要進一步瞭解如何編寫 Robolectric 測試,請參閱 Android Robolectric 網站。

隱含輸出目標

  • name.jar:測試的 Java 封存檔。
  • name-src.jar:包含來源的封存檔 (「來源 JAR」)。
  • name_deploy.jar:適合部署的 Java 部署封存檔 (僅在明確要求時建構)。

範例

如要搭配 android_local_test 使用 Robolectric,請將 Robolectric 的存放區新增至 WORKSPACE 檔案:

http_archive(
    name = "robolectric",
    urls = ["https://github.com/robolectric/robolectric-bazel/archive/<COMMIT>.tar.gz"],
    strip_prefix = "robolectric-bazel-<COMMIT>",
    sha256 = "<HASH>",
)
load("@robolectric//bazel:robolectric.bzl", "robolectric_repositories")
robolectric_repositories()
這會提取 Robolectric 必要的 maven_jar 規則。 然後,每個 android_local_test 規則都應依附 @robolectric//bazel:robolectric。請參閱下方的範例。

android_local_test(
    name = "SampleTest",
    srcs = [
        "SampleTest.java",
    ],
    manifest = "LibManifest.xml",
    deps = [
        ":sample_test_lib",
        "@robolectric//bazel:android-all",
    ],
)

android_library(
    name = "sample_test_lib",
    srcs = [
         "Lib.java",
    ],
    resource_files = glob(["res/**"]),
    manifest = "AndroidManifest.xml",
)

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

deps

標籤清單;預設值為 []

要測試的程式庫清單,以及要連結至目標的其他程式庫。這個屬性遞移閉包中 Android 規則宣告的所有資源、資產和資訊清單檔案,都會在測試中提供。

deps 中允許的規則清單包括 android_libraryaar_importjava_importjava_libraryjava_lite_proto_library

srcs

標籤清單;預設值為 []

處理後建立目標的來源檔案清單。 除非符合下文所述的特殊情況,否則必須提供。

已編譯類型為「.java」的「srcs」檔案。 為了方便閱讀,請勿將產生的 .java 來源檔案名稱放入 srcs。請改為將依附規則名稱放在 srcs 中,如下所述。

系統會解壓縮並編譯 .srcjar 類型的 srcs 檔案。(如果您需要使用 genrule 或建構擴充功能產生一組 .java 檔案,這項功能就非常實用)。

只要有至少一個上述檔案類型,系統就會忽略所有其他檔案。否則會引發錯誤。

除非指定 runtime_deps,否則 srcs 屬性為必填欄位,不得留空。

custom_package

字串;預設值為 ""

要產生 R 類別的 Java 套件。根據預設,系統會從含有規則的 BUILD 檔案所在目錄推斷套件。如果您使用這個屬性,可能也需要使用 test_class
densities

字串清單;預設值為 []

建構 APK 時要篩選的密度。如果資訊清單尚未包含超集 StarlarkListing,系統也會在資訊清單中新增對應的 compatible-screens 區段。
enable_data_binding

布林值;預設值為 False

如果為 true,這項規則會處理這項測試所用啟用資料繫結的依附元件中使用的資料繫結參照。如果沒有這項設定,資料繫結依附元件就不會產生必要的二進位層級程式碼,可能會導致建構失敗。
javacopts

字串清單;預設值為 []

這個程式庫的額外編譯器選項。 須遵守「製作變數」替代和 Bourne Shell 權杖化

這些編譯器選項會在全域編譯器選項之後傳遞至 javac。

jvm_flags

字串清單;預設值為 []

要嵌入為執行這個二進位檔產生的包裝函式指令碼中的標記清單。 須遵守 $(location) 和「Make variable」替代,以及 Bourne shell 權杖化

Java 二進位檔的包裝函式指令碼包含 CLASSPATH 定義 (可找出所有依附 JAR),並叫用正確的 Java 解譯器。包裝函式指令碼產生的指令列包含主要類別的名稱,後方加上 "$@",因此您可以在類別名稱後方傳遞其他引數。不過,如要讓 JVM 剖析引數,必須在指令列的類別名稱之前指定引數。系統會在列出類別名稱前,將 jvm_flags 的內容新增至包裝函式指令碼。

請注意,這個屬性不會影響 *_deploy.jar 輸出內容。

manifest

標籤;預設值為 None

Android 資訊清單檔案的名稱,通常為 AndroidManifest.xml。 如果定義了 resource_files 或 assets,或受測程式庫的任何資訊清單含有 minSdkVersion 標記,就必須定義這個屬性。
manifest_values

字典:字串 -> 字串;預設值為 {}

要在資訊清單中覆寫的值字典。資訊清單中的任何 ${name} 執行個體,都會替換為這個字典中對應名稱的值。applicationIdversionCodeversionNameminSdkVersiontargetSdkVersionmaxSdkVersion 也會覆寫資訊清單和 uses-sdk 標記的對應屬性。系統會忽略 packageName,並從 applicationId (如有指定) 或資訊清單中的套件設定 packageName。您不需要在規則中加入資訊清單,即可使用 manifest_values。
nocompress_extensions

字串清單;預設值為 []

要在資源 APK 中保留未壓縮狀態的副檔名清單。
plugins

標籤清單;預設值為 []

在編譯時執行的 Java 編譯器外掛程式。每當建構這項規則時,系統就會執行這個屬性中指定的所有 java_plugin。程式庫也可能從使用 exported_plugins 的依附元件繼承外掛程式。外掛程式產生的資源會納入這項規則產生的 JAR 中。
resource_configuration_filters

字串清單;預設值為 []

資源設定篩選器清單,例如「en」,可將 APK 中的資源限制為僅限「en」設定中的資源。
resource_jars

標籤清單;預設值為 []

已淘汰:請改用 java_import 和 deps 或 runtime_deps。
resource_strip_prefix

字串;預設值為 ""

要從 Java 資源中移除的路徑前置字串。

如有指定,系統會從 resources 屬性中的每個檔案移除這個路徑前置字串。如果資源檔案不在這個目錄下,就會發生錯誤。如未指定 (預設),資源檔案的路徑會根據與來源檔案的 Java 套件相同的邏輯決定。舉例來說,位於 stuff/java/foo/bar/a.txt 的來源檔案會位於 foo/bar/a.txt

runtime_deps

標籤清單;預設值為 []

僅在執行階段提供給最終二進位檔或測試的程式庫。 與一般 deps 類似,這些項目會出現在執行階段類別路徑中,但與一般 deps 不同,這些項目不會出現在編譯階段類別路徑中。這裡應列出僅在執行階段需要的依附元件。出現在 runtime_depsdeps 中的目標應由依附元件分析工具忽略。
stamp

整數;預設值為 0

是否要將建構資訊編碼為二進位檔。可能的值包括:
  • stamp = 1:一律將建構資訊蓋印到二進位檔中,即使是 --nostamp 建構作業也一樣。應避免使用這項設定,因為這可能會終止二進位檔的遠端快取,以及任何依附於該二進位檔的下游動作。
  • stamp = 0:一律以常數值取代建構資訊。這可提供良好的建構結果快取。
  • stamp = -1:建構資訊的嵌入作業由 --[no]stamp 標記控管。

除非依附元件有所變更,否則系統不會重建蓋章的二進位檔。

test_class

字串;預設值為 ""

測試執行工具要載入的 Java 類別。

這個屬性會指定要由這項測試執行的 Java 類別名稱。通常不需要設定這項屬性。如果省略這個引數,系統會使用名稱對應於這項 android_local_test 規則 name 的 Java 類別。測試類別必須加上 org.junit.runner.RunWith 註解。

use_launcher

布林值;預設值為 True

二進位檔是否應使用自訂啟動器。

如果將這項屬性設為 false,系統會忽略這個目標的 launcher 屬性和相關的 --java_launcher 旗標。

android_device

查看規則來源
android_device(name, cache, compatible_with, default_properties, deprecation, distribs, exec_compatible_with, exec_properties, features, horizontal_resolution, licenses, platform_apks, ram, restricted_to, screen_density, system_image, tags, target_compatible_with, testonly, vertical_resolution, visibility, vm_heap)

這項規則會建立 Android 模擬器,並根據指定規格進行設定。您可以透過 bazel run 指令啟動這個模擬器,也可以直接執行產生的指令碼。建議您依附現有的 android_device 規則,而非自行定義。

這項規則是 --run_under 旗標的合適目標,適用於 bazel test 和 blaze run。這個指令會啟動模擬器、將要測試/執行的目標複製到模擬器,並視情況測試或執行目標。

如果基礎 system_image 是以 X86 為基礎,且最多可針對 I686 CPU 架構進行最佳化,android_device 就支援建立 KVM 映像檔。如要使用 KVM,請在 android_device 規則中加入 tags = ['requires-kvm']

隱含輸出目標

  • name_images/userdata.dat: 包含啟動模擬器的圖片檔案和快照
  • name_images/emulator-meta-data.pb:包含必要序列化資訊,可傳遞至模擬器以重新啟動。

範例

以下範例說明如何使用 android_device。 //java/android/helloandroid/BUILD包含

android_device(
    name = "nexus_s",
    cache = 32,
    default_properties = "nexus_s.properties",
    horizontal_resolution = 480,
    ram = 512,
    screen_density = 233,
    system_image = ":emulator_images_android_16_x86",
    vertical_resolution = 800,
    vm_heap = 32,
)

filegroup(
    name = "emulator_images_android_16_x86",
    srcs = glob(["androidsdk/system-images/android-16/**"]),
)

//java/android/helloandroid/nexus_s.properties包含:

ro.product.brand=google
ro.product.device=crespo
ro.product.manufacturer=samsung
ro.product.model=Nexus S
ro.product.name=soju

這項規則會生成圖片和啟動指令碼。您可以執行 bazel run :nexus_s -- --action=start,在本機啟動模擬器。指令碼會公開下列標記:

  • --adb_port:公開 adb 的通訊埠。如要對模擬器發出 adb 指令,請透過這個通訊埠發出 adb connect 指令。
  • --emulator_port:用來公開模擬器 Telnet 管理主控台的通訊埠。
  • --enable_display:如果為 true,則啟動模擬器時會顯示畫面 (預設為 false)。
  • --action:啟動或終止。
  • --apks_to_install:要在模擬器上安裝的 APK 清單。

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

cache

整數;必要

模擬器快取分區的大小 (以 MB 為單位)。 最小值為 16 MB。
default_properties

標籤;預設值為 None

單一屬性檔案,將放置在模擬器上的 /default.prop 中。這可讓規則作者進一步設定模擬器,使其更像真實裝置 (特別是控制其 UserAgent 字串和其他行為,這些行為可能會導致應用程式或伺服器對特定裝置的行為有所不同)。這個檔案中的屬性會覆寫模擬器通常設定的唯讀屬性,例如 ro.product.model。
horizontal_resolution

整數;必要

要模擬的水平螢幕解析度 (以像素為單位)。 最小值為 240。
platform_apks

標籤清單;預設值為 []

開機時要在裝置上安裝的 APK 清單。
ram

整數;必要

要為裝置模擬的 RAM 容量 (以 MB 為單位)。 這項設定會套用至整部裝置,而不只是裝置上安裝的特定應用程式。最小值為 64 MB。
screen_density

整數;必要

模擬螢幕的密度 (以每英吋的像素為單位)。 這個值的最小值為 30 ppi。
system_image

標籤 (必填)

包含下列檔案的檔案群組:
  • system.img:系統分割區
  • kernel-qemu:模擬器將載入的 Linux 核心
  • ramdisk.img:開機時使用的 initrd 映像檔
  • userdata.img:初始使用者資料分區
  • source.properties:包含圖片相關資訊的屬性檔案
這些檔案是 Android SDK 的一部分,或是由第三方提供 (例如 Intel 提供 x86 映像檔)。
vertical_resolution

整數;必要

要模擬的垂直螢幕解析度 (以像素為單位)。 最小值為 240。
vm_heap

整數;必要

以 MB 為單位設定 Android 要為每個程序使用的虛擬機器堆積大小。 最小值為 16 MB。

android_ndk_repository

查看規則來源
android_ndk_repository(name, api_level, path, repo_mapping)

設定 Bazel 使用 Android NDK,支援以原生程式碼建構 Android 目標。

請注意,這個 android_ndk_repository 實作項目將由 Starlark 中的實作項目取代。日後將在 Starlark 版 android_ndk_repository 中,實作對 NDK 25 以上版本等未來版本的支援。如要瞭解 Starlark 版本,請參閱 rules_android_ndk

請注意,如要建構 Android 專用版本,也需要在 WORKSPACE 檔案中加入 android_sdk_repository 規則。

詳情請參閱 使用 Bazel 搭配 Android NDK 的完整說明文件

範例

android_ndk_repository(
    name = "androidndk",
)

上述範例會從 $ANDROID_NDK_HOME 找出 Android NDK,並偵測其支援的最高 API 級別。

android_ndk_repository(
    name = "androidndk",
    path = "./android-ndk-r20",
    api_level = 24,
)

上述範例會使用工作區內 ./android-ndk-r20 的 Android NDK。編譯 JNI 程式碼時,系統會使用 API 級別 24 的程式庫。

cpufeatures

Android NDK 包含 cpufeatures 程式庫,可用於在執行階段偵測裝置的 CPU。以下範例說明如何搭配 Bazel 使用 cpufeatures。

# jni.cc
#include "ndk/sources/android/cpufeatures/cpu-features.h"
...
# BUILD
cc_library(
    name = "jni",
    srcs = ["jni.cc"],
    deps = ["@androidndk//:cpufeatures"],
)

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

api_level

整數;無法設定;預設值為 0

建構時使用的 Android API 級別。如未指定,系統會使用已安裝的最高 API 級別。
path

字串;不可設定;預設值為 ""

Android NDK 的絕對或相對路徑。必須設定這個屬性或 $ANDROID_NDK_HOME 環境變數。

您可以從Android 開發人員網站 下載 Android NDK。

repo_mapping

字典:字串 -> 字串;預設值為 {}

從本機存放區名稱到全域存放區名稱的字典。這樣一來,您就能控管這個存放區的依附元件,解決工作區依附元件的問題。

舉例來說,項目 "@foo": "@bar" 會宣告,如果這個存放區依附於 "@foo" (例如依附於 "@foo//some:target"),則應在全域宣告的 "@bar" ("@bar//some:target") 中實際解析該依附元件。

android_sdk_repository

查看規則來源
android_sdk_repository(name, api_level, build_tools_version, path, repo_mapping)

設定 Bazel 使用本機 Android SDK,支援建構 Android 目標。

範例

如要為 Bazel 設定 Android SDK,最簡單的方法是在 WORKSPACE 檔案中加入名為「androidsdk」的 android_sdk_repository 規則,並將 $ANDROID_HOME 環境變數設為 Android SDK 的路徑。根據預設,Bazel 會使用 Android SDK 中安裝的最高 Android API 級別和建構工具版本。
android_sdk_repository(
    name = "androidsdk",
)

為確保建構作業可重現,pathapi_levelbuild_tools_version 屬性可以設為特定值。如果 Android SDK 未安裝指定的 API 級別或建構工具版本,建構作業就會失敗。

android_sdk_repository(
    name = "androidsdk",
    path = "./sdk",
    api_level = 19,
    build_tools_version = "25.0.0",
)

上述範例也示範如何使用與工作區相關的路徑,指向 Android SDK。如果 Android SDK 是 Bazel 工作區的一部分 (例如已簽入版本控管),這就很有用。

支援程式庫

支援程式庫位於 Android SDK 管理工具的「Android Support Repository」中。這是常見 Android 程式庫 (例如 Support 和 AppCompat 程式庫) 的版本化集合,以本機 Maven 存放區的形式封裝。android_sdk_repository 會為每個程式庫產生 Bazel 目標,這些目標可用於 android_binaryandroid_library 目標的依附元件中。

產生的目標名稱衍生自 Android 支援存放區中程式庫的 Maven 座標,格式為 @androidsdk//${group}:${artifact}-${version}。以下範例說明 android_library 如何依附於 v7 appcompat 程式庫的 25.0.0 版。

android_library(
    name = "lib",
    srcs = glob(["*.java"]),
    manifest = "AndroidManifest.xml",
    resource_files = glob(["res/**"]),
    deps = ["@androidsdk//com.android.support:appcompat-v7-25.0.0"],
)

引數

屬性
name

名稱:必填

這個目標的專屬名稱。

api_level

整數;無法設定;預設值為 0

預設建構所用的 Android API 級別。如未指定,系統會使用已安裝的最高 API 級別。

您可以使用 android_sdk 標記,覆寫特定建構作業使用的 API 級別。android_sdk_repository 會為 SDK 中安裝的每個 API 級別建立 android_sdk 目標,並命名為 @androidsdk//:sdk-${level},無論是否指定這個屬性都一樣。舉例來說,如要根據非預設的 API 級別建構,請使用 bazel build --android_sdk=@androidsdk//:sdk-19 //java/com/example:app

如要查看 android_sdk_repository 產生的所有 android_sdk 目標,可以執行 bazel query "kind(android_sdk, @androidsdk//...)"

build_tools_version

字串;不可設定;預設值為 ""

要從 Android SDK 內使用的 Android 建構工具版本。如未指定,系統會使用已安裝的最新建構工具版本。

Bazel 需要 30.0.0 以上版本的建構工具。

path

字串;不可設定;預設值為 ""

Android SDK 的絕對或相對路徑。必須設定這個屬性或 $ANDROID_HOME 環境變數。

您可以從 Android 開發人員網站下載 Android SDK。

repo_mapping

字典:字串 -> 字串;預設值為 {}

從本機存放區名稱到全域存放區名稱的字典。這樣一來,您就能控管這個存放區的依附元件,解決工作區依附元件的問題。

舉例來說,項目 "@foo": "@bar" 會宣告,如果這個存放區依附於 "@foo" (例如依附於 "@foo//some:target"),則應在全域宣告的 "@bar" ("@bar//some:target") 中實際解析該依附元件。