bundletool
是 Android Studio、Android Gradle 插件和 Google Play 用来构建 Android App Bundle 的底层工具。bundletool
可以将应用包转换为部署到设备的各种 APK。
Android SDK 包 (ASB) 及其 APK 是使用 bundletool
构建的。bundletool
也可作为命令行工具使用,因此您可以自行构建应用包和 SDK 包,并重新创建 Google Play 服务器端构建的应用 APK 或您的启用运行时 SDK 的 APK。
下载 bundletool
如果您尚未下载,请从 GitHub 仓库下载 bundletool
。
构建并测试应用包
您可以使用 Android Studio 或 bundletool
命令行工具来构建您的 Android App Bundle,然后测试从此应用包生成 APK。
构建应用包
使用 Android Studio 和 Android Gradle 插件构建和签署 Android App Bundle。但是,如果无法使用 IDE(例如,因为您正在使用持续构建服务器),您也可以从命令行构建应用包,并使用 jarsigner
对其进行签署。
有关使用 bundletool
构建应用包的更多信息,请参阅使用 bundletool 构建应用包。
从应用包生成一组 APK
构建 Android App Bundle 后,请测试 Google Play 如何使用它来生成 APK 以及这些 APK 部署到设备后的行为。
有两种方法可以测试您的应用包
- 在本地使用
bundletool
命令行工具。 - 通过 Google Play 使用测试轨道将您的包上传到 Play 管理中心。
本部分介绍了如何使用 bundletool
在本地测试您的应用包。
当 bundletool
从您的应用包生成 APK 时,它会将生成的 APK 包含在一个名为 APK set archive 的容器中,该容器使用 .apks
文件扩展名。要从您的应用包为应用支持的所有设备配置生成 APK set,请使用 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
命令时可以设置的各种标志和选项
表 1. bundletool build-apks
命令的选项
标志 | 说明 |
---|---|
--bundle=路径 |
(必需)指定使用 Android Studio 构建的应用包的路径。要了解更多信息,请阅读构建您的项目。 |
--output=路径 |
(必需)指定输出 .apks 文件的名称,该文件包含您的应用的所有 APK 工件。要在设备上测试此文件中的工件,请按照有关如何将 APK 部署到连接的设备的部分中的步骤操作。 |
--overwrite |
使用 --output 选项指定的路径覆盖任何现有的输出文件。如果您未包含此标志且输出文件已存在,您会收到构建错误。 |
--aapt2=路径 |
指定 AAPT2 的自定义路径。默认情况下,bundletool 包含其自己的 AAPT2 版本。 |
--ks=路径 |
(可选)指定用于签署 APK 的部署密钥库的路径。如果您未包含此标志,bundletool 会尝试为您使用调试密钥签署您的 APK。 |
--ks-pass=pass:密码 或 --ks-pass=file:/文件/路径 |
指定您的密钥库密码。如果您以纯文本形式指定密码,请使用 pass: 限定它。如果您传递包含密码的文件的路径,请使用 file: 限定它。如果您使用 --ks 标志指定密钥库但未指定 --ks-pass ,bundletool 会从命令行提示您输入密码。 |
--ks-key-alias=别名 |
指定您要使用的签名密钥的别名。 |
--key-pass=pass:密码 或 --key-pass=file:/文件/路径 |
指定签名密钥的密码。如果您以纯文本形式指定密码,请使用 pass: 限定它。如果您传递包含密码的文件的路径,请使用 file: 限定它。如果此密码与密钥库本身的密码相同,您可以省略此标志。 |
--connected-device |
指示 bundletool 构建针对连接设备配置的 APK。如果您未包含此标志,bundletool 会为您的应用支持的所有设备配置生成 APK。 |
--device-id=序列号 |
如果您连接了多台设备,请使用此标志指定您要部署应用的设备的序列 ID。 |
--device-spec=spec_json |
提供指向 .json 文件的路径,该文件指定了您要定位的设备配置。要了解更多信息,请转到有关如何生成和使用设备规格 JSON 文件的部分。 |
--mode=universal |
将模式设置为 universal 。如果您希望 bundletool 构建一个包含您的应用所有代码和资源的单个 APK,以便该 APK 兼容您的应用支持的所有设备配置,请使用此选项。
注意: 请记住,这些 APK 比针对特定设备配置优化的 APK 更大。但是,它们更容易与内部测试人员共享,例如,那些希望在多种设备配置上测试您的应用的人员。 |
--local-testing
|
为您的应用包启用本地测试。本地测试允许快速、迭代的测试周期,无需上传到 Google Play 服务器。 有关如何使用 |
将 APK 部署到连接的设备
生成一组 APK 后,bundletool
可以将该组中正确的 APK 组合部署到连接的设备。
例如,如果您有连接的设备运行 Android 5.0 (API level 21) 或更高版本,bundletool
会推送在该设备上运行您的应用所需的基础 APK、功能模块 APK 和配置 APK。此外,如果您的连接设备运行 Android 4.4 (API level 20) 或更低版本,bundletool
会搜索兼容的多 APK 以部署到您的设备。
要从 APK set 部署您的应用,请使用 install-apks
命令,并使用 --apks=/路径/到/apks
标志指定 APK set 的路径,如下列命令所示。如果您连接了多台设备,请通过添加 --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 set。首先,要为连接的设备生成 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 set 的设备(例如,如果您想在手头没有的设备上试用您的应用),您可以使用以下格式手动创建 JSON 文件
{
"supportedAbis": ["arm64-v8a", "armeabi-v7a"],
"supportedLocales": ["en", "fr"],
"screenDensity": 640,
"sdkVersion": 27
}
然后,您可以将此 JSON 传递给 bundle extract-apks
命令,如前一节所述。
从现有 APK set 中提取设备专用 APK
如果您有一个现有的 APK set,并且您想从中提取针对特定设备配置的 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 set 中 APK 的预计下载大小
要测量 APK set 中 APK 的预计下载大小(就像它们通过网络以压缩形式提供一样),请使用 get-size total
命令
bundletool get-size total --apks=/MyApp/my_app.apks
您可以使用以下标志修改 get-size total
命令的行为
表 2. get-size total
命令的选项
标志 | 说明 |
---|---|
--apks=路径 |
(必需)指定要测量其下载大小的现有 APK set 文件的路径。 |
--device-spec=路径 |
指定设备规格文件的路径(来自 get-device-spec 或手动构建),用于匹配。您可以指定部分路径以评估一组配置。 |
--dimensions=尺寸
| 指定计算大小估算时使用的维度。接受逗号分隔的列表:SDK 、ABI 、SCREEN_DENSITY 和 LANGUAGE 。要测量所有维度,请指定 ALL 。 |
--instant |
测量启用即时功能的 APK 的下载大小,而不是可安装 APK 的下载大小。默认情况下,bundletool 测量可安装 APK 的下载大小。 |
--modules=模块 |
指定 APK set 中要考虑在测量中的逗号分隔模块列表。bundletool 命令会自动包含指定 set 的所有依赖模块。默认情况下,该命令会测量首次下载时安装的所有模块的下载大小。 |
构建包含 SDK 包依赖项的应用包(实验性)
您可以从命令行构建包含 Android SDK 包 (ASB) 依赖项的 Android App Bundle,并使用 jarsigner 签署它。
每个应用包模块都包含一个模块协议缓冲区 (.pb
) 文件:runtime_enabled_sdk_config.pb
。此文件包含应用包模块所依赖的 SDK 列表。有关此文件的完整定义,请参阅 runtime_enabled_sdk_config.proto
文件。
要构建包含 SDK 包依赖项的应用包,请按照有关使用 bundletool 构建应用包的部分中的步骤操作,并将 runtime_enabled_sdk_config.pb
文件添加到每个应用模块包含已编译代码和资源的 zip 文件中。
runtime_enabled_sdk_config.pb
文件中一些值得注意的字段
证书摘要: 用于签署 SDK APK 的密钥的证书的 SHA-256 摘要。这与Android SDK Archive 格式中
SdkMetadata.pb
文件中的证书相对应。资源包 ID: 在为将 SDK 嵌入到应用中而生成 APK 时,此 SDK 中所有资源重新映射到的包 ID。这支持向后兼容性。
一个 SDK 只能出现在一个模块中。如果多个模块依赖于同一个 SDK,则应删除此依赖项的重复项并将其移动到基础模块。不同的模块不能依赖于不同版本的 SDK。
从包含 SDK 包依赖项的应用包生成 APK(实验性)
要从您的应用包生成 APK,请按照有关从您的应用包生成一组 APK 的部分或有关生成设备专用 APK set 的部分中的步骤操作,并向 bundletool build-apks
命令提供应用所依赖的 SDK。这些 SDK 可以以 SDK 包格式或 SDK Archive 格式提供。
您可以通过添加 --sdk-bundles
标志将 SDK 作为 SDK 包提供,如下所示
bundletool build-apks --bundle=app.aab --sdk-bundles=sdk1.asb,sdk2.asb \ --output=app.apks
您可以通过添加 --sdk-archives
标志将 SDK 作为 SDK Archive 提供,如下所示
bundletool build-apks --bundle=app.aab --sdk-archives=sdk1.asar,sdk2.asar \ --output=app.apks
为不支持 SDK 库的设备从包含 SDK 包依赖项的应用包生成 APK
Android 13 之前的设备不支持安装 SDK 库或在 SDK 运行时中运行它们。当您使用 --sdk-bundles
或 --sdk-archives
选项运行 bundletool build-apks
时,Bundletool 隐藏了向后兼容性的复杂性,并会从同一个应用包生成 APK set 的多个变体。这些多个变体针对具有不同功能的设备
- 对于较新的设备有一个变体,其中 SDK 作为独立于应用的包安装,并且应用 APK 不包含任何 SDK 内容。
- 对于较旧的设备有一个或多个变体,其中 SDK APK 作为额外的 APK 分割添加到应用 APK set 中。SDK APK 属于应用包。在这种情况下,SDK 运行时在设备上的应用运行时中模拟。
与为不带 SDK 依赖项的应用包生成 APK 类似,bundletool extract-apks
和 bundletool install-apks
会从连接设备或提供的设备配置的最佳变体中返回一组过滤后的 APK。
对于您只对为较旧设备上的特定应用从 SDK Archive 生成 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
命令会生成应用 APK 的子集,该子集对应于应用包名下的 SDK 内容。您可以将这些 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
命令时可以设置的各种标志和选项。
表 3. 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 set archive 的容器中,该容器使用 .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
命令时可以设置的各种标志和选项。
表 4. bundletool build-sdk-apks
命令的选项
标志 | 说明 |
---|---|
--sdk-bundle |
(必需)SDK 包的路径。必须具有 .asb 扩展名。 |
--output |
(必需)默认情况下,要创建 APK set Archive 的路径。此外,如果您使用 --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 set Archive 中。如果设置为 DIRECTORY ,它会将 APK 输出到由 --output 指定的目录中。 |
--verbose |
如果设置,此选项会在标准输出中打印有关命令执行的额外信息。 |
--version-code |
SDK 版本代码。这是 Android 平台用于安装 APK 的版本代码,而不是 SDK 版本。此选项可以设置为任意值。如果未设置,则默认为 0。 |
--overwrite |
如果设置,此选项会覆盖任何以前的现有输出。 |
部署、提取和测量 SDK APK 的大小
您可以按照与应用相同的步骤将 APK 部署到连接的设备、从现有 APK set 中提取设备专用 APK 以及测量 APK set 中 APK 的预计下载大小。
从 SDK 包生成 SDK Archive
将 ASB 上传到您的分发渠道(例如 Google Play)后,ASB 会转换为 Android SDK Archive (.asar
),用于通过 Maven 分发给应用开发者。有关此格式的更多详细信息,请参阅有关SDK Archive 格式规范的部分。
构建 ASB 后,您可以使用 bundletool build-sdk-asar
命令在本地测试 Android SDK Archive 的生成,如下列代码所示
bundletool build-sdk-asar --sdk-bundle=sdk.asb --output=sdk.asar \ --apk-signing-key-certificate=keycert.txt
下表详细描述了在使用 bundletool build-sdk-asar
命令时可以设置的各种标志和选项。
表 5. bundletool build-sdk-asar
命令的选项
标志 | 说明 |
---|---|
--apk-signing-key-certificate |
(必需)SDK APK 签名证书的路径。这是与您在 build-sdk-apks 命令中用于签署 APK 的密钥相对应的证书。 |
--output |
(必需)要创建 .asar 文件的路径。 |
--sdk-bundle |
(必需)SDK 包的路径。必须具有 .asb 扩展名。 |
--overwrite |
如果设置,此选项会覆盖任何以前的现有输出。 |
启用运行时的 SDK 格式(实验性)
启用运行时的 SDK 引入了两种 Android 文件格式
- 用于将启用运行时的 SDK 发布到应用商店的Android SDK 包 (
.asb
)。 - 用于在 Maven 上分发启用运行时的 SDK 的Android SDK Archive (
.asar
)。
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
:一个 zip 文件,包含从 SDK 生成 APK 所需的所有数据。SdkModulesConfig.pb
:一个 proto 格式的配置文件。此文件包含 SDK 名称、版本以及框架 SDK 入口点(SandboxedSdkProvider
)的类名。有关完整定义,请参阅sdk_modules_config.proto
文件。base/
:包含 SDK 代码和资源的单个模块。manifest/
:proto 格式的 SDK 清单。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 Archive 格式
Android SDK Archive 是 Maven 上启用运行时 SDK 的分发格式。它是一个带有 .asar
文件扩展名的 zip 文件。该文件包含应用构建工具生成依赖于您的启用运行时 SDK 的 Android App Bundle 所需的所有信息。

以下列表更详细地描述了 Android SDK Archive 文件中的一些内容
SdkMetadata.pb
:一个 proto 格式的配置文件,包含 SDK 名称、版本以及用于签署为此 SDK 生成的 APK 的密钥的证书摘要。有关完整定义,请参阅sdk_metadata.proto
文件。modules.resm
:一个 zip 文件,包含从 SDK 生成 APK 所需的所有数据。这与Android SDK 包中的.resm
文件相同。AndroidManifest.xml
:文本 XML 格式的 SDK 清单文件。
其他资源
要了解有关使用 bundletool
的更多信息,请观看应用包:使用 bundletool 和 Play 管理中心测试包。