bundletool
是 Android Studio、Android Gradle 插件和 Google Play 用于构建 Android 应用包的基础工具。bundletool
可以将应用包转换为部署到设备的各种 APK。
Android SDK 包 (ASB) 及其 APK 均使用 bundletool
构建。它也作为命令行工具提供,因此您可以自行构建应用包和 SDK 包,并重新创建 Google Play 服务器端对您的应用 APK 或您 已启用运行时的 SDK 的 APK 的构建。
下载 bundletool
如果您尚未下载,请从 GitHub 代码库 下载 bundletool
。
构建和测试应用包
您可以使用 Android Studio 或 bundletool
命令行工具构建 Android 应用包,然后测试从此应用包生成 APK。
构建应用包
使用 Android Studio 和 Android Gradle 插件 构建和签署 Android 应用包。但是,如果无法使用 IDE(例如,因为您使用的是持续构建服务器),您也可以 从命令行构建应用包 并使用 jarsigner
对其进行签署。
有关使用 bundletool
构建应用包的更多信息,请参阅 使用 bundletool 构建应用包。
从应用包生成一组 APK
构建 Android 应用包后,测试 Google Play 如何使用它生成 APK 以及这些 APK 部署到设备后的行为。
您可以通过两种方式测试应用包
- 在本地使用
bundletool
命令行工具。 - 通过 Google Play 将您的应用包上传到 Play Console,并使用测试轨道。
本部分介绍如何使用 bundletool
在本地测试应用包。
当 bundletool
从您的应用包生成 APK 时,它会将生成的 APK 包含在一个名为APK 集成归档文件的容器中,该容器使用 .apks
文件扩展名。要为应用支持的所有设备配置从应用包生成 APK 集,请使用 bundletool build-apks
命令,如下所示
bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
如果要将 APK 部署到设备,还需要包含应用的签署信息,如下面的命令所示。如果您未指定签署信息,bundletool
会尝试使用调试密钥为您签署 APK。
bundletool build-apks --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks --ks=/MyApp/keystore.jks --ks-pass=file:/MyApp/keystore.pwd --ks-key-alias=MyKeyAlias --key-pass=file:/MyApp/key.pwd
下表详细描述了在使用bundletool build-apks
命令时可以设置的各种标志和选项。
标志 | 描述 |
---|---|
--bundle=path |
(必需) 指定使用 Android Studio 构建的应用 bundle 的路径。要了解更多信息,请阅读构建您的项目。 |
--output=path |
(必需) 指定输出.apks 文件的名称,该文件包含应用的所有 APK 工件。要测试此文件中的工件,请按照有关如何将 APK 部署到连接的设备部分中的步骤操作。 |
--overwrite |
使用--output 选项指定的路径覆盖任何现有的输出文件。如果您不包含此标志并且输出文件已存在,则会收到构建错误。 |
--aapt2=path |
指定 AAPT2 的自定义路径。默认情况下,bundletool 包含其自己的 AAPT2 版本。 |
--ks=path |
(可选) 指定用于签署 APK 的部署密钥库的路径。如果您不包含此标志,bundletool 将尝试使用调试签名密钥签署您的 APK。 |
--ks-pass=pass:password 或 --ks-pass=file:/path/to/file |
指定您的密钥库密码。如果您以纯文本形式指定密码,请使用pass: 限定它。如果您传递包含密码的文件的路径,请使用file: 限定它。如果您使用--ks 标志指定密钥库,而没有指定--ks-pass ,则bundletool 会提示您从命令行输入密码。 |
--ks-key-alias=alias |
指定要使用的签名密钥的别名。 |
--key-pass=pass:password 或 --key-pass=file:/path/to/file |
指定签名密钥的密码。如果您以纯文本形式指定密码,请使用pass: 限定它。如果您传递包含密码的文件的路径,请使用file: 限定它。如果此密码与密钥库本身的密码相同,则可以省略此标志。 |
--connected-device |
指示bundletool 构建针对连接设备配置的 APK。如果您不包含此标志,bundletool 将为您的应用支持的所有设备配置生成 APK。 |
--device-id=serial-number |
如果您连接了多个设备,请使用此标志指定要将应用部署到的设备的序列 ID。 |
--device-spec=spec_json |
提供.json 文件的路径,该文件指定要定位的设备配置。要了解更多信息,请转到有关如何生成和使用设备规范 JSON 文件的部分。 |
--mode=universal |
将模式设置为universal 。如果您希望bundletool 构建一个包含应用所有代码和资源的单个 APK,以便 APK 与应用支持的所有设备配置兼容,则可以使用此选项。
注意: 请记住,这些 APK 比针对特定设备配置优化的 APK 大。但是,它们更容易与内部测试人员共享,例如,内部测试人员希望在多个设备配置上测试您的应用。 |
--local-testing
|
启用应用 bundle 进行本地测试。本地测试允许快速迭代测试周期,而无需上传到 Google Play 服务器。 有关如何使用 |
将 APK 部署到连接的设备
生成一组 APK 后,bundletool
可以将该集中正确的 APK 组合部署到连接的设备。
例如,如果您有一个运行 Android 5.0(API 级别 21)或更高版本的连接设备,则bundletool
会推送在该设备上运行您的应用所需的基 APK、功能模块 APK 和配置 APK。或者,如果您的连接设备运行的是 Android 4.4(API 级别 20)或更低版本,则bundletool
会搜索一个兼容的多 APK 以部署到您的设备。
要从 APK 集部署您的应用,请使用install-apks
命令并使用--apks=/path/to/apks
标志指定 APK 集的路径,如以下命令所示。如果您连接了多个设备,请通过添加--device-id=serial-id
标志来指定目标设备。
bundletool install-apks --apks=/MyApp/my_app.apks
生成特定于设备的 APK 集
如果您不想为应用支持的所有设备配置构建 APK 集,则可以使用--connected-device
选项构建仅针对连接设备配置的 APK,如以下命令所示。如果您连接了多个设备,请通过包含--device-id=serial-id
标志来指定目标设备。
bundletool build-apks --connected-device --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
生成和使用设备规范 JSON 文件
bundletool
可以生成一个针对 JSON 文件指定的设备配置的 APK 集。要首先为连接的设备生成 JSON 文件,请运行以下命令
bundletool get-device-spec --output=/tmp/device-spec.json
bundletool
会在工具的目录中为您的设备创建 JSON 文件。然后,您可以将文件传递给bundletool
以生成一组仅针对该 JSON 文件中描述的配置的 APK,如下所示
bundletool build-apks --device-spec=/MyApp/pixel2.json --bundle=/MyApp/my_app.aab --output=/MyApp/my_app.apks
手动创建设备规范 JSON
如果您无法访问要为其构建目标 APK 集的设备(例如,如果您想在没有的设备上尝试您的应用),则可以使用以下格式手动创建 JSON 文件
{
"supportedAbis": ["arm64-v8a", "armeabi-v7a"],
"supportedLocales": ["en", "fr"],
"screenDensity": 640,
"sdkVersion": 27
}
然后,您可以将此 JSON 传递给bundle extract-apks
命令,如上一节所述。
从现有 APK 集中提取特定于设备的 APK
如果您有现有的 APK 集,并且想要从中提取针对特定设备配置的 APK 子集,则可以使用extract-apks
命令并指定设备规范 JSON,如下所示
bundletool extract-apks --apks=/MyApp/my_existing_APK_set.apks --output-dir=/MyApp/my_pixel2_APK_set.apks --device-spec=/MyApp/bundletool/pixel2.json
测量 APK 集中 APK 的估计下载大小
要测量 APK 集中 APK 的估计下载大小(如通过网络压缩传输时的下载大小),请使用get-size total
命令
bundletool get-size total --apks=/MyApp/my_app.apks
您可以使用以下标志修改get-size total
命令的行为
标志 | 描述 |
---|---|
--apks=path |
(必需) 指定要测量下载大小的现有 APK 集文件的路径。 |
--device-spec=path |
指定设备规范文件(来自get-device-spec 或手动构建)的路径,以用于匹配。您可以指定部分路径以评估一组配置。 |
--dimensions=dimensions
| 指定计算大小估计值时使用的维度。接受以下逗号分隔的列表:SDK 、ABI 、SCREEN_DENSITY 和LANGUAGE 。要跨所有维度测量,请指定ALL 。 |
--instant |
测量启用即时功能的 APK 的下载大小,而不是可安装 APK 的下载大小。默认情况下,bundletool 测量可安装 APK 的下载大小。 |
--modules=modules |
指定 APK 集中要考虑测量的模块的逗号分隔列表。bundletool 命令会自动包含指定集的任何依赖模块。默认情况下,该命令会测量首次下载期间安装的所有模块的下载大小。 |
使用 SDK bundle 依赖项构建应用 bundle(实验性)
您可以使用命令行构建具有 Android SDK bundle (ASB) 依赖项的 Android 应用 bundle,并使用jarsigner对其进行签名。
每个应用 bundle 模块都包含一个模块协议缓冲区(.pb
)文件:runtime_enabled_sdk_config.pb
。此文件包含应用 bundle 模块依赖的 SDK 列表。有关此文件的完整定义,请参阅runtime_enabled_sdk_config.proto
文件。
要使用 SDK bundle 依赖项构建应用 bundle,请按照有关使用 bundletool 构建应用 bundle部分中的步骤操作,并将runtime_enabled_sdk_config.pb
文件添加到每个应用模块的 zip 文件中,其中包含已编译的代码和资源。
一些runtime_enabled_sdk_config.pb
文件中值得注意的字段
证书摘要:用于签署 SDK 的 APK 的密钥的证书的 SHA-256 摘要。这对应于Android SDK 归档格式中
SdkMetadata.pb
文件中的证书。资源包 ID:将此 SDK 中的所有资源重新映射到的包 ID,用于生成用于将 SDK 嵌入到应用中的 APK。这可以实现向后兼容性。
SDK 只能出现在一个模块中。如果多个模块依赖于同一个 SDK,则应对该依赖项进行重复数据删除并将其移动到基本模块。不同的模块不能依赖于 SDK 的不同版本。
从具有 SDK bundle 依赖项的应用 bundle 生成 APK(实验性)
要从您的应用 bundle 生成 APK,请按照有关从应用 bundle 生成 APK 集部分或有关生成特定于设备的 APK 集部分中的步骤操作,并向bundletool build-apks
命令提供应用依赖的 SDK。这些 SDK 可以以 SDK bundle 格式或 SDK 归档格式提供。
您可以通过添加--sdk-bundles
标志以 SDK bundle 的形式提供 SDK,如下所示
bundletool build-apks --bundle=app.aab --sdk-bundles=sdk1.asb,sdk2.asb \ --output=app.apks
您可以通过添加--sdk-archives
标志以 SDK 归档的形式提供 SDK,如下所示
bundletool build-apks --bundle=app.aab --sdk-archives=sdk1.asar,sdk2.asar \ --output=app.apks
为不支持 SDK 库的设备从具有 SDK bundle 依赖项的应用 bundle 生成 APK
Android 13 之前的设备不支持安装 SDK 库或在 SDK 运行时中运行它们。当您使用 bundletool build-apks
命令并带有 --sdk-bundles
或 --sdk-archives
选项时,Bundletool 会隐藏向后兼容性的复杂性,并从同一个应用包生成多个 APK 集变体。这些多个变体针对具有不同功能的设备。
- 对于较新的设备,有一个变体,其中 SDK 作为与应用分开的软件包安装,并且应用 APK 不包含任何 SDK 内容。
- 对于较旧的设备,存在一个或多个变体,其中 SDK APK 作为附加的 APK 分割添加到应用 APK 集中。SDK APK 属于应用包。在这种情况下,SDK 运行时在设备上的应用运行时中进行模拟。
类似于您如何为没有 SDK 依赖项的应用包生成 APK,bundletool extract-apks
和 bundletool install-apks
会从连接设备或提供的设备配置的最佳变体中返回一组经过过滤的 APK。
对于您只对为特定应用的旧设备生成来自 SDK 归档文件的 APK 分割的高级用例,请使用以下所示的 bundletool build-sdk-apks-for-app
命令
bundletool build-sdk-apks-for-app --app-properties=app-properties.json \ --sdk-archive=sdk.asar --output=sdk.apks
app-properties
文件应包含 runtime_enabled_sdk_config.proto
文件中描述的字段。以下是 app-properties
文件的示例:
{
"package_name": "com.my.app",
"version_code": 1234,
"min_sdk_version": 21,
"resources_package_id": 0x7e
}
bundletool build-sdk-apks-for-app
命令会生成与应用包名称下的 SDK 内容相对应的应用 APK 子集。您可以将这些 APK 与包含应用内容的其他 APK 结合起来。例如,如果您分别构建它们并增量安装,并在不支持 SDK 运行时的设备上一起安装。
构建和测试 SDK 包(实验性)
您可以使用 bundletool
构建 ASB 并测试生成安装和分发所需的文件。
构建 SDK 包
您可以从命令行构建 ASB,并使用 jarsigner 对其进行签名。
要构建 SDK 包,请按照以下步骤操作:
按照与应用包相同的步骤,以 proto 格式生成 SDK 包的清单和资源。
像处理应用模块一样,将 SDK 的编译代码和资源打包到一个基本 zip 文件中。
生成一个
SdkModulesConfig.pb.json
文件和一个SdkBundleConfig.pb.json
文件,使其格式与 Android SDK 包规范 中描述的格式匹配。使用以下所示的
bundletool build-sdk-bundle
命令构建您的 ASB:
bundletool build-sdk-bundle --sdk-bundle-config=SdkBundleConfig.pb.json \ --sdk-modules-config=SdkModulesConfig.pb.json \ --modules=base.zip --output=sdk.asb
下表详细描述了使用 bundletool build-sdk-bundle
命令时可以设置的各种标志和选项。
标志 | 描述 |
---|---|
--modules |
(必填) 您要从中构建最终 ASB 的模块文件。 |
--output |
(必填) 您希望构建 ASB 的路径。 |
--sdk-modules-config |
(必填) 描述 SDK 模块配置的 JSON 文件的路径。要了解如何格式化 JSON 文件,请参阅 Android SDK 包规范 部分。 |
--sdk-bundle-config |
描述 SDK 包配置的 JSON 文件的路径。要了解如何格式化 JSON 文件,请参阅 Android SDK 包规范 部分。 |
--metadata-file |
包含 ASB 元数据的文件。标志值的格式为 <bundle-path>:<physical-file> ,其中 <bundle-path> 表示 SDK 包元数据目录内的文件位置,而 <physical-file> 是一个包含要存储的原始数据的文件。该标志可以重复使用。 |
--overwrite |
如果设置了此选项,则会覆盖任何以前存在的输出。 |
从 SDK 包生成 APK
构建 ASB 后,您可以通过使用以下代码所示的 bundletool build-sdk-apks
命令生成其 APK 来在本地测试 SDK 包。
bundletool build-sdk-apks --sdk-bundle=sdk.asb --output=sdk.apks
当 bundletool
从您的 SDK 包生成 APK 时,该工具会将 APK 包含在一个名为“APK 集归档文件”的容器中,该容器使用 .apks
文件扩展名。bundletool
从 SDK 包生成一个针对所有设备配置的独立 APK。
如果要将 ASB 部署到设备,则还需要包含应用的签名信息,如下面的命令所示:
bundletool build-sdk-apks --sdk-bundle=sdk.asb --output=sdk.apks \ --ks=keystore.jks \ --ks-pass=file:/keystore.pwd \ --ks-key-alias=KeyAlias \ --key-pass=file:/key.pwd
下表详细描述了使用 bundletool build-sdk-apks
命令时可以设置的各种标志和选项。
标志 | 描述 |
---|---|
--sdk-bundle |
(必填) SDK 包的路径。必须具有扩展名 .asb 。 |
--output |
(必填) 默认情况下,您希望创建 APK 集归档文件的路径。或者,如果您使用 --output-format=DIRECTORY ,则这是您希望存储生成 APK 的目录的路径。 |
--ks |
您要用于签名生成 APK 的密钥库的路径。 |
--ks-key-alias |
密钥库中要用于签名生成 APK 的密钥的别名。 |
--key-pass |
密钥库中要用于签名生成 APK 的密钥的密码。 如果您以明文形式传递密码,则必须在值前面加上 如果未设置此标志,则会尝试使用密钥库密码。如果失败,则命令行终端会提示您输入密码。 |
--ks-pass |
要用于签名生成 APK 的密钥库的密码。 如果您以明文形式传递密码,则必须在值前面加上 如果未设置此标志,则命令行终端会提示您输入密码。 |
--aapt2 |
要使用的 AAPT2 二进制文件的路径。 |
--output-format |
生成 APK 的输出格式。默认情况下,此选项设置为 APK_SET ,它会将 APK 输出到创建的 APK 集归档文件中。如果设置为 DIRECTORY ,则会将 APK 输出到 --output 指定的目录中。 |
--verbose |
如果设置了此选项,则会在标准输出中打印有关命令执行的额外信息。 |
--version-code |
SDK 版本代码。这是 Android 平台用于安装 APK 的版本代码,而不是 SDK 版本。此选项可以设置为任意值。如果未设置,则默认为 0。 |
--overwrite |
如果设置了此选项,则会覆盖任何以前存在的输出。 |
部署、提取和测量 SDK APK 的大小
您可以按照应用使用的相同步骤将 APK 部署到连接的设备、从现有的 APK 集提取特定于设备的 APK 以及测量 APK 集中 APK 的估计下载大小。
从 SDK 包生成 SDK 归档文件
将 ASB 上传到您的分发渠道(例如 Google Play)后,ASB 会转换为 Android SDK 归档文件 (.asar
),以便通过 Maven 分发给应用开发者。有关格式的更多详细信息,请参阅有关 SDK 归档文件格式规范 的部分。
构建 ASB 后,您可以使用以下代码所示的 bundletool build-sdk-asar
命令在本地测试 Android SDK 归档文件的生成。
bundletool build-sdk-asar --sdk-bundle=sdk.asb --output=sdk.asar \ --apk-signing-key-certificate=keycert.txt
下表详细描述了使用 bundletool build-sdk-asar
命令时可以设置的各种标志和选项。
标志 | 描述 |
---|---|
--apk-signing-key-certificate |
(必填) SDK APK 签名证书的路径。这是与您在 build-sdk-apks 命令中用于签名 APK 的密钥对应的证书。 |
--output |
(必填) 您希望创建 .asar 文件的路径。 |
--sdk-bundle |
(必填) SDK 包的路径。必须具有扩展名 .asb 。 |
--overwrite |
如果设置了此选项,则会覆盖任何以前存在的输出。 |
运行时启用 SDK 格式(实验性)
运行时启用 SDK 引入了两种 Android 文件格式:
- Android SDK 包 (
.asb
),用于将运行时启用 SDK 发布到应用商店。 - Android SDK 归档文件 (
.asar
),用于通过 Maven 分发运行时启用 SDK。
Android SDK 包格式
SDK 包是运行时启用 SDK 的发布格式。它包含所有 SDK 代码和资源,包括 SDK 依赖的任何库的代码。它不包含 SDK 依赖的其他运行时启用 SDK 的代码和资源。
Android SDK 包 (ASB) 是一个带 .asb
扩展名的已签名 zip 文件。SDK 代码和资源在其组织方式上与 APK 中的类似。ASB 还包含几个配置文件,有助于生成可安装的 APK。
以下列表更详细地描述了一些 ASB 文件:
SdkBundleConfig.pb
:一个以 proto 格式表示的配置文件,其中包含 SDK 依赖的运行时启用 SDK 列表。有关完整定义,请参阅sdk_bundle_config.proto
文件。modules.resm
:一个包含生成 SDK APK 所需的所有数据的 zip 文件。SdkModulesConfig.pb
:一个以 proto 格式表示的配置文件。此文件包含 SDK 名称、版本以及框架 SDK 入口点的类名 (SandboxedSdkProvider
)。有关完整定义,请参阅sdk_modules_config.proto
文件。base/
:包含 SDK 代码和资源的单个模块。manifest/
:SDK 的清单文件,采用 proto 格式。dex/
:已编译的 DEX 格式代码。可以提供多个 DEX 文件。res/
、lib/
、assets/
:这些目录与典型 APK 中的目录相同。在生成 SDK 的 APK 时,这些目录中的路径将被保留。root/
:此目录存储稍后将重新定位到 SDK APK 根目录的文件。例如,它可能包含 SDK 使用Class.getResource()
方法加载的基于 Java 的资源。此目录内的路径也将被保留。
BUNDLE-METADATA
:此目录包含元数据文件,其中包含对工具或应用商店有用的信息。此类元数据文件可能包括 ProGuard 映射和 SDK 的 DEX 文件的完整列表。此目录中的文件不会打包到 SDK 的 APK 中。
Android SDK 归档格式
Android SDK 归档是 Maven 上支持运行时的 SDK 的分发格式。它是一个扩展名为 .asar
的 zip 文件。该文件包含应用构建工具生成依赖于支持运行时的 SDK 的 Android 应用包所需的所有信息。
以下列表更详细地描述了一些 Android SDK 归档文件。
SdkMetadata.pb
:一个采用 proto 格式的配置文件,其中包含 SDK 名称、版本以及用于对为该 SDK 生成的 APK 签名的密钥的证书摘要。有关完整定义,请参阅sdk_metadata.proto
文件。modules.resm
:一个 zip 文件,其中包含从 SDK 生成 APK 所需的所有数据。这与 Android SDK Bundle 中的.resm
文件相同。AndroidManifest.xml
:SDK 的清单文件,采用文本 XML 格式。
其他资源
要了解有关使用 bundletool
的更多信息,请观看 应用包:使用 bundletool 和 Play Console 测试应用包。