2. Android App Bundle 的文件结构

2.1 核心概念:模块化发布单元

Android App Bundle(AAB)不是传统的 APK,而是一个标准化容器,内部按模块组织资源与代码。每个模块对应一组功能或分发条件,Google Play 在生成最终 APK 时会根据设备配置只选择需要的模块。AAB 文件实际上是 ZIP 格式,扩展名为 .aab,其顶级目录结构固定如下:

目录 / 文件职责分发角色
base/应用的核心代码、资源、清单所有设备必须包含
feature_*/按需下载的功能模块可通过 Play Feature Delivery 延迟或按条件下发
asset_pack/大型资源包(纹理、音视频)通过 Play Asset Delivery 按需或即时分发
BundleConfig.pb元数据:版本、压缩选项、签名配置构建工具和 Play 商店读取
BUNDLE-SIGNATURE可选的数字签名文件验证完整性
关键区别:base 是强制模块,feature_ 和 asset_pack 是可选模块,它们共同构成了“一次构建,智能拆分”的模型。

2.2 文件结构原理图解

Android App Bundle 顶层结构 app.aab (ZIP) base/ (核心模块) feature_*/ (功能模块) asset_pack/ (资源包) BundleConfig.pb BUNDLE-SIGNATURE 各模块典型内容 • base/ : AndroidManifest.xml, classes.dex, res/, lib/ (必需) • feature_*/ : 独立清单、资源、代码(按需延迟下载) • asset_pack/ : .pck 文件(纹理、地形、语音包),不包含代码

2.3 生活化类比:可拆装的集装箱

想象一个国际货运集装箱(app.aab),内部被分成三个区域:

  • base 就像集装箱的底盘和钢架——无论什么运输方式都必须有它,否则货物无法固定。
  • feature_* 是货柜里的独立包装箱。买家可以只买 A 箱(基础功能)或同时买 B 箱(高级功能);商家按需发货,节省运费。
  • asset_pack 是贴在集装箱外侧的专用消防设备包,只有运到特定港口才需要取出,且不占主货舱。
  • BundleConfig.pb 相当于集装箱的运输清单和海关文件,告诉港口机器怎样拆包、哪些货物可以合并。

2.4 常见误区与关键区别

误区 1:base 模块可以像普通 module 一样任意拆分
事实:base 是 AAB 的根模块,必须包含完整的 AndroidManifest.xml 和所有 mipmap-* 启动图标资源,否则 Play 商店拒绝上架。你不能将 base 设计为“空壳”,它必须包含应用启动所需的所有入口代码。
误区 2:feature_ 目录名称可以随意起
事实:必须遵循 feature_<模块名> 格式,构建工具以此识别模块类型。若命名为 myfeature/ 而非 feature_myfeature/,Gradle 会将其视为普通资源目录而非动态功能模块,导致无法按需下发。

与 APK 的关键区别:APK 将所有代码和资源打包成一个扁平文件,而 AAB 通过模块目录清晰分离关注点。APK 中的 assets/ 对应 AAB 的 asset_pack/,但 AAB 的 asset_pack 可以独立配置压缩、安装时间(install-time / fast-follow / on-demand)。

2.5 自测练习题

  1. 题目 1:一个 AAB 文件是否可以不包含 base/ 目录?如果不可以,至少需要包含哪些强制文件?

    (提示:参考核心定义与 Play 商店要求)

  2. 题目 2:假设你有一个大型 3D 游戏,希望主 APK 不携带高精度贴图,而是在用户进入“画质设置”后按需下载。你应该使用哪个模块来存放这些贴图?请说明选择的理由。
答案参考
1. 必须包含 base/,且必须包含 AndroidManifest.xml、classes.dex 和启动图标资源。缺少任意一项都将被 Play 拒绝。
2. 使用 asset_pack/(Play Asset Delivery)。因为贴图属于大型资源,不需要代码逻辑,且可以设置为 on-demand 或 fast-follow 模式。若使用 feature_* 则必须包含代码和清单,增加冗余。

2.6 应用边界说明

AAB 文件结构的设计目标是支持模块化分发和动态交付。以下是其适用范围与限制:

  • 适用场景:大型应用(>150MB)、需要按条件下发功能(如国家、设备能力)、希望对 APK 大小进行精细控制。
  • 不适用场景:纯库项目(因为没有 base 模块)、独立插件通过非 Google Play 渠道分发(因为 AAB 依赖 Play 商店的拆分过程)。
  • 边界注意:所有 feature_* 和 asset_pack 都必须在 base 模块的清单中通过 <dist:module> 声明,否则 Play 商店将忽略它们。构建时需确保 Gradle 插件版本 ≥ 3.6.0。