Android App Bundle 是您上传到 Google Play 的文件(文件扩展名为 .aab
)。
应用包是签名的二进制文件,它将应用的代码和资源组织成模块,如图 1 所示。每个模块的代码和资源的组织方式与您在 APK 中找到的类似,这是有道理的,因为这些模块中的每一个都可能生成为单独的 APK。然后,Google Play 使用应用包生成提供给用户的各种 APK,例如基本 APK、功能 APK、配置 APK,以及(对于不支持拆分 APK 的设备)多 APK。蓝色部分(如 drawable/
、values/
和 lib/
目录)表示 Google Play 用于为每个模块创建配置 APK 的代码和资源。
图 1. 包含一个基础模块、两个功能模块和两个素材包的 Android App Bundle 的内容。
以下列表更详细地描述了应用包的一些文件和目录
- base/、feature1/ 和 feature2/:这些顶层目录中的每一个都代表您应用的不同模块。您应用的基础模块始终包含在应用包的
base
目录中。但是,每个功能模块的目录名称由模块清单中的split
属性指定。要了解更多信息,请阅读功能模块清单。 - asset_pack_1/ 和 asset_pack_2/:对于大型、对图形要求较高的应用或游戏,您可以将素材模块化为素材包。素材包因其大尺寸限制而非常适合游戏。您可以根据三种交付模式自定义每个素材包下载到设备上的方式和时间:安装时、快速跟进和按需。所有素材包均托管在 Google Play 上并从 Google Play 提供。要详细了解如何将素材包添加到应用包,请参阅Play Asset Delivery 概览。
- BUNDLE-METADATA/:此目录包含对工具或应用商店有用的元数据文件。此类元数据文件可能包括 ProGuard 映射和应用 DEX 文件的完整列表。此目录中的文件未打包到应用的 APK 中。
- 模块协议缓冲区 (
*.pb
) 文件:这些文件提供元数据,有助于向应用商店(例如 Google Play)描述每个应用模块的内容。例如,BundleConfig.pb
提供有关包本身的信息,例如用于构建应用包的构建工具的版本;而native.pb
和resources.pb
描述每个模块中的代码和资源,这在 Google Play 针对不同设备配置优化 APK 时非常有用。 - manifest/:与 APK 不同,应用包将每个模块的
AndroidManifest.xml
文件存储在此单独的目录中。 - dex/:与 APK 不同,应用包将每个模块的 DEX 文件存储在此单独的目录中。
- res/、lib/ 和 assets/:这些目录与典型 APK 中的目录相同。当您上传应用包时,Google Play 会检查这些目录,并仅打包满足目标设备配置的文件,同时保留文件路径。
root/:此目录存储的文件稍后会重新定位到包含此目录所在模块的任何 APK 的根目录。例如,应用包的
base/root/
目录可能包含您的应用使用Class.getResource()
加载的基于 Java 的资源。这些文件稍后会重新定位到您应用的基础 APK 以及 Google Play 生成的每个多 APK 的根目录。此目录中的路径也保留。也就是说,目录(及其子目录)也会重新定位到 APK 的根目录。
拆分 APK 概览
提供优化应用的一个基本组成部分是 Android 5.0(API 级别 21)及更高版本上提供的 split APK(拆分 APK)机制。拆分 APK 与普通 APK 非常相似,它们包含编译后的 DEX 字节码、资源和 Android 清单。但是,Android 平台能够将多个已安装的拆分 APK 视为单个应用。也就是说,您可以安装多个可访问通用代码和资源的拆分 APK,并且它们在设备上显示为一个已安装的应用。
拆分 APK 的好处在于能够将一个庞大的 APK(即包含您的应用支持的所有功能和设备配置的代码和资源的 APK)分解为更小、独立的软件包,这些软件包可以按需安装到用户的设备上。
例如,一个拆分 APK 可能包含仅少数用户需要的附加功能的代码和资源,而另一个拆分 APK 则仅包含特定语言或屏幕密度的资源。当用户请求或设备需要时,会下载并安装这些拆分 APK 中的每一个。
下文介绍了可在设备上协同安装以提供完整应用体验的不同类型的 APK。您将在本页面的后续部分中了解如何配置您的应用项目以支持这些 APK。
- 基本 APK:此 APK 包含所有其他拆分 APK 都可以访问的代码和资源,并提供应用的基本功能。当用户请求下载您的应用时,此 APK 会首先下载并安装。这是因为只有基本 APK 的清单才包含您应用的服务、内容提供商、权限、平台版本要求和对系统功能的依赖项的完整声明。Google Play 根据您项目的应用(或基本)模块为您的应用生成基本 APK。如果您担心减小应用的初始下载大小,请务必记住,此模块中包含的所有代码和资源都包含在您应用的基本 APK 中。
- 配置 APK:这些 APK 中的每一个都包含用于特定屏幕密度、CPU 架构或语言的原生库和资源。当用户下载您的应用时,他们的设备仅下载并安装以其设备为目标的配置 APK。每个配置 APK 都是基本 APK 或功能模块 APK 的依赖项。也就是说,它们是与提供代码和资源的 APK 一起下载和安装的。与基础模块和功能模块不同,您无需为配置 APK 创建单独的模块。如果您使用标准实践为您的基础模块和功能模块组织替代的、特定于配置的资源,则 Google Play 会自动为您生成配置 APK。
- 功能模块 APK:这些 APK 中的每一个都包含您使用功能模块模块化的应用功能的代码和资源。然后,您可以自定义该功能下载到设备上的方式和时间。例如,使用 Play Core 库,功能可以在基本 APK 安装到设备上之后按需安装,以向用户提供附加功能。考虑一个聊天应用,它仅在用户请求使用拍照和发送照片功能时才下载并安装该功能。由于功能模块可能在安装时不可用,因此您应将所有通用代码和资源包含在基本 APK 中。也就是说,您的功能模块应假定在安装时只有基本 APK 的代码和资源可用。Google Play 根据您项目的功能模块为您的应用生成功能模块 APK。
考虑一个包含三个功能模块并支持多种设备配置的应用。图 1 描绘了应用各种 APK 的依赖关系树可能是什么样子。请注意,基本 APK 构成树的头部,所有其他 APK 都依赖于基本 APK。(如果您对这些 APK 的模块在 Android App Bundle 中如何表示感到好奇,请参阅Android App Bundle 格式。)
图 1. 使用拆分 APK 提供的应用的依赖关系树
请记住,您无需自己构建这些 APK — Google Play 会使用您使用 Android Studio 构建的单个签名应用包为您完成此操作。要详细了解应用包格式以及如何构建应用包,请访问构建、部署和上传 Android App Bundle。
运行 Android 4.4(API 级别 19)及更低版本的设备
由于运行 Android 4.4(API 级别 19)及更低版本的设备不支持下载和安装拆分 APK,因此 Google Play 转而为这些设备提供一个针对设备配置优化的单个 APK,称为多 APK。也就是说,多 APK 代表您的完整应用体验,但不包含不必要的代码和资源,例如针对其他屏幕密度和 CPU 架构的代码和资源。
但是,它们确实包含您的应用支持的所有语言的资源。例如,这允许用户更改应用的首选语言设置,而无需下载不同的多 APK。
多 APK 不具备后续按需下载功能模块的能力。要在此 APK 中包含功能模块,您必须在创建功能模块时禁用按需或启用融合。
请记住,使用应用包,您无需为应用支持的每种设备配置构建、签名、上传和管理 APK。您仍然只需为整个应用构建并上传一个应用包,Google Play 会为您处理其余部分。因此,无论您是否计划支持运行 Android 4.4 或更低版本的设备,Google Play 都会为您和您的用户提供灵活的服务机制。
用户语言更改
使用应用包,设备仅下载运行应用所需的代码和资源。因此,对于语言资源,用户的设备仅下载与设备设置中当前选择的一种或多种语言匹配的应用语言资源。
当用户在设备设置中切换语言时,Google Play 可能需要下载并安装一些额外的拆分 APK,然后应用才能以新语言显示。
Google Play 会在切换后立即尝试下载附加语言。如果用户设备离线、下载失败或资源过大,Google Play 会在设备条件更有利时在后台再次尝试下载。在运行 Android 9.0(API 级别 28)或更低版本的设备上,如果在安装新语言拆分 APK 期间您的应用在前台运行,则应用将被终止。
如果您的应用要求设备随时提供所有语言,您可以在构建配置中禁用语言拆分。
如果您的应用需要独立于设备设置中选择的用户语言下载其他语言(例如,实现应用内语言选择器),则可以使用 Play Core 库按需下载这些语言。