重要提示:从 2021 年 8 月起,新应用需要使用 Android App Bundle 才能在 Google Play 中发布。现在,Play Feature Delivery 或 Play Asset Delivery 支持大小超过 150 MB 的新应用。
Android App Bundle 是一种发布格式(并不是可安装文件),文件后缀名为 .aab
,是一个压缩文件,其中包含了应用的所有经过编译的代码和资源,APK文件的生成和签名都由 Google Play 完成。Google Play 在使用 App Bundle 生成 APK 的过程中,会针对每种设备配置进行优化,只保留特定设备需要的代码和资源,因此特定的设备会下载的 APK 的体积会得到一定程度减少。
举个简单的例子,你的项目中包含x86
、armabi
、armeabi-v7a
多种 CPU 架构的 so 库,直接生成的 APK 中直接包含了这三种架构 so 库,但是安装的设备的 CPU 只会是其中一种架构,那么其他的 so 库就是冗余的资源,下载安装的设备根本用不到。使用 Android App Bundle 就是根据设备生成对应的 APK,减少冗余资源(包括图片资源、so 库等),从而 APK 体积也可以得到减小。
减少冗余资源只是使用 Android App Bundle 的其中一个用处,它还有一个更重要的用法是可以将应用进行模块化划分,生成多个 APK,用户首次只需要下载较小的安装包,在使用过程中根据需求下载相应的模块,而且还可以实现对不需要的模块进行写作。使用 App Bundle 格式发布应用时,可以选择使用 Play 功能分发(Play Feature Delivery),它可以让您向应用项目中添加功能模块,这些模块包含的功能和资源仅在您指定的条件下才会添加到您的应用中,或者在稍后运行时下载 Play 核心库(Play Core Library)时使用。使用App Bundle 格式发布游戏时,开发者可以使用 Play 资产分发(Play Asset Delivery),它是 Google Play 用于分发拥有大量资产的游戏的解决方案,为开发者提供灵活的分发方式和高效的性能。
注意事项:Android App Bundle 只是一种 Google Play 的发布格式,并不是可安装文件,需要经过Google Play处理生成最终的可安装 APK 文件。可参考:bundletool 工具使用详解
对于大多数应用而言,要支持 Android App Bundle 并不费力。因为应用基础 APK 中包含代码和资源的模块是一个标准的应用模块,当使用 Android Studio 新建项目的时候得到的默认模块就是这样的一个模块,在此模块下的 build.gradle
脚本文件中使用 application
插件(com.android.application
),并为应用的基础功能提供所需的代码和资源。
apply plugin: 'com.android.application'
如果项目支持 Kotlin,还可以在 build.gradle
中这么声明应用模块:
plugins {
// The standard application plugin creates your app's base module.
id("com.android.application")
}
除了给应用提供核心功能之外,基础模块中还提供许多关系整个应用项目的编译配置和清单配置。
对现有大多数应用项目,你无需更改基础模块中编译配置的任何内容。然而,如果你需要往项目中增加功能模块,或者你需要使用多个 APK 发布应用,你必须记住要对基础模块的编译配置的某些方面进行修改。
使用 Android App Bundle,你无需关注上传到 Google Play 的多个 APK 的版本号,你只需要关注应用基础模块的版本号即可。在基础模块下的 build.gradle
配置版本号,如下示例所示:
android {
defaultConfig {
// ...
// 只需要在基础模块下指定应用的版本号
versionCode 1
versionName "1.0"
}
}
在您上传 App Bundle 之后,Google Play会使用基础模块中定义的应用版本号,为从这个 App Bundle 生成的所有 APK 的版本号进行重新设置。因此,当设备下载并安装您的应用,所以分割的 APK 都有一样的版本号。
当您需要使用新的代码或者资源更新您的应用时,必须更新应用基础模块下的版本号,并且构建一个完整的新 App Bundle。将新的 App Bundle 上传到 Google Play后,会重新生成一系列基于基础模块新的版本号的 APK。随后,当用户更新应用时,Google Play 服务端会更新设备上安装的所有 APK 的版本号,设备上所有安装的 APK 都会更新到新版本。
注意事项:由 App Bundle 生成的 APK,版本号是以应用基础模块的版本号决定的。另外,还有许多编译配置也会忽略掉功能模块下的配置,只使用基础模块中的配置,比如
minifyEnabled
。
默认情况下,支持为每一组语言资源、屏幕密度资源和 ABI 库生成配置 APK。在应用基础模块下的 build.gradle
脚本文件中,通过 android.bundle
代码块可以启用或者禁用对一个(或多个)配置 APK的支持。如下示例所示:
android {
// 在构建 Android App Bundles时,splits 块将会被忽略.
// 你可以移除它,除非你想在构建 App Bundle 的同时构建多 APK。
splits {...}
// 改为使用 bundle 块来控制你想要你的 App Bundle 支持哪些类型的配置 APK
bundle {
// 语言资源
language {
// 这个属性默认为 true,你可以设置为 false 关闭为语言资源生成配置 APK。
// 启用后,将会为每种语言资源生成一个配置 APK。
// 禁用后,不会为语言资源生成配置 APK,而是在基础 APK 中包含所有的语言资源。
enableSplit = false
}
// 屏幕密度资源
density {
// 这个属性默认为 true,你可以设置为 false 关闭为屏幕密度资源生成配置 APK。
enableSplit = true
}
// ABI库资源
abi {
// 这个属性默认为 true,你可以设置为 false 关闭为ABI资源生成配置 APK。
enableSplit = true
}
}
}
Google Play会根据用户设备系统设定的语言来决定安装哪个语言资源。如果用户在已经下载并安装您的应用之后变更系统默认语言,并且您的应用支持变更后的语言,设备就会从 Google Play 中请求下载对应语言的配置 APK。对于一些应用内部自带语言选择器,独立于系统语言设置,动态改变应用的语言。因为Google Play下载对应语言配置 APK 只会根据系统语言变更时才会发生,这种情况下你必须确保不会因为资源确实而闪退,你可以在编译配置中,将 android.bundle.language.enableSplit
属性配置成 false(基础 APK 中将包含所有配置的语言),或者使用 Play Core 库按需下载语言库。
注意事项:下载配置APK并更新应用,对于此类更新,并不会更改应用的版本代码。
.aab
) 文件结构 Android App Bundle 文件后缀名为 .aab
,是一个压缩文件,包含了应用的所有经过编译的代码和资源,以及签名信息。如下图所示:
META-IF/
:签名信息。BUNDLE-METADATA/
:Bundle文件额外信息,包含编译依赖库相关信息等。base/
:程序相关文件,包含经过编译后的代码和资源等BundleConfig.pb
:Bundle文件配置 base/
目录下包含程序相关文件,目录结构跟 apk
文件类似,如下所示:
base/root/
:在安装文件(.apk
)根目录中的一些文件,比如 kotlin 文件、签名信息等。base/res/
:程序资源base/manifest/
:程序清单文件base/lib/
: 程序 ABI 库(Native 库)base/dex/
:经过编译只有的代码 dexbase/assets/
:程序资产base/***.pb
:资源、资产、Native库等配置信息如果您使用 Android Studio 开发,可以经过简单的几步导出经过签名的 App Bundle。
Build -> Generate Singned Bundle or APK
,在弹出窗口中选择 Android App Bundle
,点击下一步选择签名,最终导出 Android App Bundle 文件(.aab
)。如果在 build.gradle
中配置了签名选项,可以在 Gradle 窗口中,依次展开 基础模块名 -> Tasks -> build
,然后双击下面的 bundle
(或者 bundleRelease
)执行任务,执行完成之后会在 基础模块名/build/outputs/bundle/
目录下找到已签名的 App Bundle 文件(亦可以直接在 Android Studio 的命令行中执行 gradlew bundle
命令构建) 因为Android App Bundle 文件(.aab
)只是一种发布格式,并不是可安装文件,因此不能直接安装在测试设备上,但是可以通过 Android Studio 将构建的 App Bundle 文件,部署到已连接的测试设备上(即针对测试设备生成对应配置的 APK 并安装运行),因为 Android Studio IDE 和 Google Play 使用的是同一种工具提取 APK 并安装到设备上。默认情况下,当您从 Android Studio 部署应用到连接的设备上时,IDE 会构建和部署连接设备对应的配置 APK(因为构建单个配置 APK 比构建所有配置 APK 要快得多)。在Android Studio 中部署 App Bundle,可以参考一下步骤:
Run -> Edit Configurations
;run/debug
配置(Android Studio 中显示为 Android App 类型);General
标签,在 Installation Options
下面的 Deplay
选项中,选择 APK from app bundle
,然后点击 Apply
保存配置;Run -> Run
(或者点击工具栏的运行按钮),Android Studio 就会构建 App Bundle,并且根据生成的 App Bundle 为连接的设备生成对应的配置 APK 并安装运行。注意事项:使用 Android Studio 测试部署 App Bundle 时,并不会生成 APK 文件,而是直接安装到连接的设备并运行,如果需要测试生成配置 APK,请参考:使用 bundletool 为 Android App Bundle 生成 APK 集合。
可以在命令行中使用 Android Studio 和 Google Play 用来构建 App Bundle 并将其转换成一系列 APK 的工具。也就是说,您可以在命令行中使用这些工具,在本地构建 Android App Bundle 并部署应用。
That is, you can invoke these tools from the command line to locally build and deploy your app from an Android App Bundle.
在命令行中构建 App Bundle,有两种方法,一种是Android Gradle 插件,另一种是 BundleTools 工具。
gradlew :<模块名>:bunbleDebug | bundleRelease
注意事项:
1. 不能使用 apksigner 对 App Bundle 进行签名,要对 App Bundle 进行签名,请使用 jarsigner;
2. Android Gradle 插件只能构建 App Bundle,但不能生成配置 APK,如需要生成配置 APK,请参考:使用 bundletool 为 Android App Bundle 生成配置 APK。
bundletool build-bundle --modules=base.zip --output=mybundle.aab
命令生成最终的 Android App Bundle文件(.aab
)。因步骤比较繁杂,之类也不做详细介绍了。使用 Android Gradle 插件可以非常容易地构建 Android App Bundle,但是需要使用 bundletool 从 App Bundle 中部署应用到连接的测试设备上。您可以通过BundleTool命令行测试应用和模拟 Google Play 分发。使用 bundletool 可以实现以下不同类型的测试场景:
使用 bundletool 生成 APK集合,使用以下命令:
bundletool build-apks --bundle=my_app.aab --output=my_app.apks
关于 bundletool 的详细使用,请参考:bundletool 工具使用详解