3. 传统APK vs App Bundle
这个话题,是我在日常面试中几乎必问的一道题。很多同学能把APK和AAB的概念背得滚瓜烂熟,但一问到构建方式到底差在哪、签名流程有什么坑,就开始支支吾吾了。说实话,刚接触AAB那会儿,我也觉得它不就是换个打包格式嘛,后来在项目中真正落地了一遍,才发现差异比想象中大得多。
这一章我们就来彻底掰扯清楚。我从三个最核心的维度来拆解:构建方式、分发流程、签名机制。这三个点,是理解AAB和APK本质差异的关键。
3.1 构建方式:一次性完整构建 vs 按需组装
3.1.1 传统APK:全部资源打包在一起
传统APK的构建流程,说白了就是用Gradle把代码、资源、原生库、Manifest等所有东西揉成一个完整的zip包。你运行一次 ./gradlew assembleRelease,出来的就是一个几十上百MB的APK文件。这个包是自包含的——用户下载后直接安装,不需要联网再去拿任何额外资源。
这样做的好处是简单。缺点是——不管用户的设备是啥配置,他都得下载这个完整的包。比如你的App里有为平板设计的layout-hdpi资源,手机用户也得下载。我在项目里见过一个极端的例子:一个电商App,只因为放了几套不同屏幕密度的启动图,包体积就多了8MB。而实际上,90%的用户只用得到其中一套。
3.1.2 App Bundle:构建中间产物,按需产出
AAB不一样。你运行 ./gradlew bundleRelease 生成的 .aab 文件,本质上是一个中间产物。它里面包含了所有资源,但并不会直接安装到设备上。真正的APK生成,是发生在Google Play的服务器端——它根据用户的设备配置(屏幕密度、CPU架构、语言等),只抽取需要的部分,组装成一个优化后的APK。
我个人习惯把AAB理解成"资源仓库",而Google Play就是那个按需取用的管理员。
bundletool 生成APK来测试,发现资源找不到。后来排查了半天,发现是因为我们没有正确配置 resConfigs,导致AAB的资源拆分逻辑出了问题。记住了:AAB的构建产物不是最终安装包,一定要通过 bundletool 或者Google Play测试渠道来验证。
3.2 分发流程:直接分发 vs 动态交付
3.2.1 APK分发的"全量模式"
APK的分发路径非常直接:开发者上传到应用商店,用户下载完整包,安装到设备上。每次更新,无论改动多小,用户都得下载整个新包。我记得有个项目只改了3行代码,但因为资源文件被重新打包,最终生成的APK还是比上一版大了2MB。用户感知到的就是"又更新了,又下了几十MB"。
3.2.2 AAB分发的"按需模式"
AAB的分发流程增加了两个关键的中间环节:Google Play的优化处理和按需交付。用户下载时,Play会根据他的设备生成专属APK。而且后续更新支持增量更新——只下载变化的部分。你想想看,如果只改了3行代码,用户可能只需要下载几百KB的补丁包,体验差别非常大。
3.3 签名机制:开发者主导 vs 平台托管
签名这块,是很多团队迁移AAB时最容易踩坑的地方。我见过不止一个团队因为没理解清楚签名机制的变化,导致线上事故。
3.3.1 APK签名:密钥完全在开发者手里
APK的签名方案经历了V1→V2→V3的演进。你用 jarsigner 或 Android Studio 自带的签名工具,用自己的密钥给APK打上签名。密钥一旦丢失,你就永远无法更新这个应用了。我在2019年就经历过一次——合作方的密钥管理员离职了,密钥文件找不到,最后只能被迫换个包名重新上架,所有用户都得重新下载,损失惨重。
# APK签名命令示例(V2方案)
jarsigner -keystore myrelease.keystore -sigalg SHA256withRSA -digestalg SHA-256 -signedjar app-signed.apk app-unsigned.apk alias_name
3.3.2 AAB签名:上传密钥+分发密钥的双层体系
AAB引入了上传密钥(Upload Key)和分发密钥(Distribution Key)的两层体系。你用上传密钥签名AAB并上传到Google Play,Play再用分发密钥重新签名后分发给用户。这样做最大的好处是:即使上传密钥丢了,你也可以联系Google Play支持更换,不影响线上用户。我曾经就帮一个客户处理过这种情况,整个过程大概花了2周,但至少App还能正常更新。
不过这里有一个很容易忽视的细节:你必须在Play Console中注册Google Play应用签名。如果忘了注册,AAB虽然能上传,但无法正常分发。
3.4 核心差异速查表
| 对比维度 | 传统APK | App Bundle |
|---|---|---|
| 构建产出 | 完整APK(自包含) | .aab 中间产物(需Play处理) |
| 签名方案 | 开发者单密钥(V1/V2/V3) | 上传密钥 + Play分发密钥 |
| 分发方式 | 直接分发完整包 | 按设备配置动态分发 |
| 更新方式 | 全量下载新包 | 增量更新 + 按需加载 |
| 包体积 | 大(含所有无关资源) | 小(仅包含设备所需) |
| 密钥恢复 | 密钥丢失=应用死亡 | 可联系Play支持更换 |
3.5 整体对比流程图
下面这张图把APK和AAB从构建到用户安装的完整链路做了一个并列对比。你可以直观地看到,AAB在中间增加了"平台动态处理"这一层,这也是两者最本质的差异所在。
3.6 避坑指南:从APK迁移到AAB的实战建议
说了这么多,最后给几条我自己在实际项目中淌过的坑,希望对你有帮助。
- 迁移前先确认签名方案。 如果当前APK用的是V1签名,必须先发一个V2/V3签名的新版本,否则无法启用Google Play应用签名。我见过有团队因为这个原因,被迫重新发布了一个过渡版本,白白耽误了两周。
- 在Play Console中提前注册应用签名密钥。 这个操作要在上传AAB之前完成。一旦上传了AAB,就无法再更换签名方案了。
- 使用bundletool做本地验证。 你可以在本地用
bundletool build-apks命令生成APK集合,然后安装到不同配置的设备上测试,确保资源拆分和按需加载逻辑正确。 - 关注动态功能模块的加载时机。 如果你的App用了动态功能模块,要特别留意按需加载的场景。我曾在一个项目里发现,某个功能模块在弱网环境下加载失败,导致用户无法使用核心功能。最后加了重试机制和加载状态提示才解决问题。
嗯,这一章的内容就到这里。APK和AAB的核心差异,说白了就是"一次打包"和"按需组装"的思维转变。构建方式变了,分发流程变了,签名机制也跟着变了。这三个变化环环相扣,理解清楚它们,后续在实战中才能踩准节奏。