3. AAB与APK的区别及优势

说实话,我刚接触 Android App Bundle 那会儿,第一反应是:“这不就是换了个壳的 APK 吗?”

真干了几个项目之后才发现,这俩玩意儿的底层逻辑完全不同。咱们今天就把它们掰开揉碎,看看 AAB 到底比 APK 强在哪,以及为什么灰度发布这件事儿,用 AAB 简直是天生一对。


3.1 打包方式的根本差异

APK 的打包,说白了就是把所有资源一股脑塞进一个 Zip 包里。你想想,一个 100MB 的 APK,里头可能包含 10 种语言的字符串、5 种分辨率的高清图、3 种架构的 so 库。用户下载的时候,哪怕他只用中文 + 1080p + arm64,也得把整个包拖下来。

我早期维护过一个海外社交 App,包体 80MB,每次发版都在想“用户流量不要钱吗?”后来改成 AAB,看数据惊了——平均下载量降了 40%。原因很简单:AAB 打包的时候,它把资源按“配置维度”拆开了。

核心区别一览

对比项APK(传统方式)AAB(Android App Bundle)
打包产物单个 APK 文件.aab 文件(包含所有模块 + 分块资源)
资源处理不做拆分,全部包含按语言、屏幕密度、CPU 架构拆分为“模块分片”
签名时间构建时签名上传至 Google Play,由 Play 签名并生成“带签名的 APK”
最终交付用户直接下载 APK 安装Google Play 根据用户设备生成“专用 APK”再下发

嗯,这里要注意:AAB 本身不能直接安装到手机上。它是个上传格式,Google Play 拿到后,会按设备配置生成一个“裁剪过的 APK”给用户。这个过程叫做“动态交付”(Dynamic Delivery)。

3.2 体积优化:AAB 凭什么更小?

你可能会问:“AAB 拆开之后,单个用户的下载体积能小多少?”

来,看个真实数据。我去年做过一个工具类 App,原始 APK 65MB。改成 AAB 并配置了拆分后,用户平均下载包只有 38MB。节省了近 42%。

为什么会这样?

  • 语言资源:你一个中文 App,没必要让用户下载日文、法文、阿拉伯文的字符串。APK 强迫你“买一送十”,AAB 只给用户“买一送一”。
  • 图片资源:屏幕密度从 mdpi 到 xxxhdpi,像素差好几倍。AAB 只下发对应密度及可回退的密度,不会塞那些永远用不上的巨图。
  • 原生库:arm64-v8a、armeabi-v7a、x86……APK 得全放。AAB 挑出用户设备对应的架构,其他直接砍掉。

个人经验:我在做灰度方案时,曾经把包含 4 套 so 库的 APK 直接切换成 AAB,单渠道包体积从 120MB 降到 35MB。当时测试同事以为我写错了脚本……其实这就是 AAB 的正常表现。

3.3 动态分发能力:按需加载的魅力

APK 是“一次下载,全部安装”。AAB 允许你把功能模块做成“按需安装”的组件。比如你的 App 里有个 AR 拍照功能,可能 80% 的用户从来不用。那这个功能模块就可以做成“按需分发”。用户第一次点 AR 相机时,后台默默下个几 MB 的模块,装好再用。

这对于灰度发布来说,简直是神器。为什么?

  1. 你可以只把新功能模块推给灰度组,其他用户看不到也下载不到。
  2. 如果灰度发现 BUG,直接撤回模块,不需要用户更新整个 App。
  3. 灰度结束后,把模块状态改为“默认安装”,所有后续增量用户自动带上。

还记得我前面提到的“按需模块”吗?它不仅仅是体积优化,更是发布策略上的一个分身术。我负责过一个电商项目,想在双十一前灰度测试“直播购物”功能。如果用 APK 传统方式,得打两个包(有直播版 + 无直播版),然后分别配置渠道。维护两个版本号,想想就头大。

换成 AAB + 按需模块后,只维护一份 AAB,直播模块是“on-demand”。灰度组在 Play Console 里配置 5% 用户可下载该模块,剩下的用户压根感知不到有这个功能存在。出了问题,一键关掉分发即可。回滚速度从“发版 + 审核”变成“秒级配置生效”。

避坑指南:我曾经在灰度某功能时,没注意“按需模块”的下载时机。结果灰度用户进入页面后,先弹出一个“正在加载模块”的 Toast,然后才下载安装,体验很糟糕。后来我改用“条件延迟下载”——用户空闲时 WiFi 下预加载,体验才正常。

3.4 为什么灰度发布更适合同步 App Bundle?

咱们把灰度发布的目标再明确一下:

  • 控制暴露范围:只让一小部分用户看到新功能。
  • 快速迭代:发现问题能立刻停止推送。
  • 数据对比:灰度组和对照组之间需要有明确的版本分界。

传统 APK 做灰度,要么用多渠道包(一个 APK 对应一个灰度组),要么用服务端开关(同一个 APK 里内置功能开关)。多渠道包管理成本高,而且维护多个 APK 的版本号容易出错。服务端开关倒是方便,但开关控制的代码始终在用户手机里,容易被逆向破解或抓包篡改。

AAB 给了一个更优雅的方案:细分版本 + 按需模块。

  • 细分版本:AAB 可以选择只给灰度用户下发“带新功能的新版模块”,其他人继续用旧版。这相当于天然将用户分成了两组。
  • 按需模块:新功能以模块打包,只有灰度用户才会下载该模块。未下载的用户根本不包含任何新功能代码,安全性和隔离性都更好。
  • 包体积优势:因为进行了资源拆分,灰度用户的下载量更小,灰度测试的成本(流量、存储)也降低了。

我个人的建议:如果你的灰度发布频率大于每月一次,或者灰度功能涉及大量资源(图片、布局、so库),那么用 AAB 替换 APK 几乎是零坑升级。否则,继续用老路也能凑合。


知识结构总览

AAB vs APK 在灰度发布中的对比 传统 APK 打包 所有资源打包在一起 用户下载完整 APK 灰度需多渠道包或开关 Android App Bundle 分发 资源按语言/密度/架构拆分 Google Play 生成专用 APK 按需模块支持精细化灰度 VS ✎ 灰度发布最佳选择:AAB • 包体积平均减少 30%~50%,用户下载更快 • 按需模块实现功能级灰度,无需双包维护 • 回滚秒级生效,代码不留在未覆盖用户设备中

3.5 总结:一张表看透 AAB vs APK

维度APKAAB
打包粒度单体胖包模块化 + 资源分片
用户下载体积打包时的全量数据仅下载当前设备所需
灰度灵活性多渠道包 / 代码开关按需模块 + Play Console 配置
回滚效率需重新发版关闭模块分发,秒级生效
安全隔离性代码均在安装包内未授权用户不包含模块代码
适用场景简单功能、小团队复杂模块、频繁灰度、大团队

说到底,AAB 不是为了取代 APK 而生的,它是为了响应动态分发和包体积优化这个时代需求而生的。你只要做过一次灰度切 AAB 的迁移,就再也不想回到以前那个“打五个不同渠道号 APK”的日子了。