aab文件转换为apk文件
前言#
在 2018 年的 Google I/O 大会上,Google 向 Android 引入了 Android App Bundle,缩写为 AAB:
在2021年,Google宣布Google Play 将开始要求从 2021 年 8 月开始使用 Android App Bundle 发布新应用,这将取代 APK 作为标准发布格式。
APK#
APK: Android应用程序包(Android application package)是Android操作系统使用的一种应用程序包文件格式,用于分发和安装移动应用及中间件。一个Android应用程序的代码想要在Android设备上运行,必须先进行编译,然后被打包成为一个被Android系统所能识别的文件才可以被运行,而这种能被Android系统识别并运行的文件格式便是APK。
可以使用Kotlin、Java 等多种语言编写Android应用程序,编译前项目的结构大概如图:

典型 Android 应用模块的构建流程, 按照以下常规步骤执行:

编译器将您的源代码转换成 DEX 文件(Dalvik 可执行文件,其中包括在 Android 设备上运行的字节码),并将其他所有内容转换成编译后的资源。 APK 打包器将 DEX 文件和编译后的资源组合成单个 APK。不过,必须先为 APK 签名,然后才能将应用安装并部署到 Android 设备上。 APK 打包器使用调试或发布密钥库为 APK 签名: 如果您构建的是调试版应用(即专用于测试和分析的应用),则打包器会使用调试密钥库为应用签名。Android Studio 会自动使用调试密钥库配置新项目。 如果您构建的是打算对外发布的发布版应用,则打包器会使用发布密钥库为应用签名。如需创建发布密钥库,请参阅在 Android Studio 中为应用签名。 在生成最终 APK 之前,打包器会使用 zipalign 工具对应用进行优化,以减少其在设备上运行时所占用的内存。
一个 APK 文件包含 Android 应用的所有内容,它也是 Android 设备用来安装应用的文件。APK 是遵循 ZIP 文件格式的文件,Android SDK 工具会将代码连同任何数据和资源文件编译成后缀为 .apk 的APK归档文件。使用Android Studio的APK Analyzer tool 分析样例helloworld.apk,可以看出该APK的归档文件概况:

APK 文件由一个 Zip 压缩文件组成,其中包含构成应用的所有文件。这些文件包括 Java 类文件、资源文件和包含已编译资源的文件。
上述的 APK 包含以下目录:
META-INF/:包含CERT.SF和CERT.RSA签名文件,以及MANIFEST.MF清单文件。res/:包含未编译到resources.arsc中的资源。resources.arsc:包含已编译的资源。此文件包含res/values/文件夹的所有配置中的 XML 内容。打包工具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以及未直接包含在resources.arsc文件中的内容(例如布局文件和图片)的路径。classes.dex:包含以Dalvik/ART虚拟机可理解的 DEX 文件格式编译的类。AndroidManifest.xml:包含核心 Android 清单文件。此文件列出了应用的名称、版本、访问权限和引用的库文件。该文件使用 Android 的二进制 XML 格式。
而有的APK还会包含:
lib/:包含特定处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi、armeabi-v7a、arm64-v8a、x86、x86_64 和 mips。assets/:包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。
而上述的文件目录,可看出一些APK的打包情况。如可以将平台兼容性、资源等文件打包进APK。
往往,在单一APK打包文件时,为了兼容硬件规格、语言等,就会将兼容性的文件一同打包在同一个APK文件中。随着Android的发展,需要打包到APK中的东西越来越多。这种就会出现一个问题,就是很多文件是安装机器不需要下载、存储的。而且构建分APK上传到商店,也需要上传多份APK,不是一个好的版本控制方式。
而AAB打包方式,减小APK大小,改变交付方式,很好的解决了这种臃肿的打包方式。
AAB#
Android App Bundle为新 App 动态化框架(Android App Bundle,缩写为 AAB),即是一个动态的载体文件。AS生成的aab文件,可将语言、屏幕大小、硬件架构等内容全部覆盖。


使用AS生成aab文件,生成的aab文件为1.2MB,而APK文件大小为1.6MB:

使用Android Studio的APK Analyzer tool 分析样例helloworld.aab,可以看出该APK的归档文件概况:

BUNDLE-METADATA/:此目录包含元数据文件,其中包含对工具或应用商店有用的信息。此类元数据文件可能包含 ProGuard 映射和应用的 DEX 文件的完整列表。此目录中的文件未打包到您应用的 APK 中。- 模块协议缓冲区 (
*.pb) 文件:这些文件提供了一些元数据,有助于向各个应用商店(如 Google Play)说明每个应用模块的内容。例如,BundleConfig.pb提供了有关 bundle 本身的信息(如用于构建 app bundle 的构建工具版本),native.pb和resources.pb说明了每个模块中的代码和资源,这在 Google Play 针对不同的设备配置优化 APK 时非常有用。 manifest/:与 APK 不同,app bundle 将每个模块的AndroidManifest.xml文件存储在这个单独的目录中。dex/:与 APK 不同,app bundle 将每个模块的 DEX 文件存储在这个单独的目录中。res/、lib/和assets/:这些目录与典型 APK 中的目录完全相同。当上传 App Bundle 时,Google Play 会检查这些目录并且仅打包满足目标设备配置需求的文件,同时保留文件路径。root/:此目录存储的文件之后会重新定位到包含此目录所在模块的任意 APK 的根目录。
由此可见AAB的一些优势:
- 体积轻盈:根据设备的不同属性,进行优化生成APK
- 应用模块化:开发者可将应用的功能拆分下来,允许用户自行下载
- 免下载体验:AAB 具有免安装分发特性,可让用户在 Google Play 里即可体验APP
格式转换#
据谷歌官方文档描述“Android App Bundle 是您上传到 Google Play 的一种文件(文件扩展名为 .aab)”。 也就是说,AAB的转换,可以通过Google Play来帮助用户实现。而想要在本地测试aab转换后的apk,就可以通过bundletool 工具实现转换, Github下载地址为 https://github.com/google/bundletool/releases
bundletool 是一种底层工具,可供 Gradle、Android Studio 和 Google Play 用于构建 Android App Bundle 或将 App Bundle 转换为部署到设备的各种 APK
使用bundletool生成apks:
java -jar bundletool-all-1.7.0.jar build-apks --bundle=app-debug.aab --output=helloworld.apks
生成的apks是一个压缩包,查看apks压缩包,主要由toc.pb文件、splits文件夹、standalones文件夹组成:

使用密钥文件可以生成签名的APK文件:
java -jar bundletool.jar build-apks --bundle=test.aab --output=test.apks --ks=keystore.jks --ks-pass=pass:your_keystore_password --ks-key-alias=your_key_alias --key-pass=pass:your_key_password
只提取一个APK:
java -jar bundletool.jar build-apks --bundle=test.aab --output=nhl.apks --mode=universal

提取一个签名的通用APK文件:
java -jar bundletool.jar build-apks --bundle=nhl.aab --output=test.apks --overwrite --mode=universal -ks=keystore.jks --ks-pass=pass:your_keystore_password --ks-key-alias=your_key_alias --key-pass=pass:your_key_password
安装apks到当前设备,运行成功:
bundletool install-apks --apks=test.apks

aab2apk#
在某些测试场景中,需要对aab进行转换,且获取到aab文件的一些基本信息,编写了aab2apk小工具。
在Windows上的使用,如下:
aab2apk.exe -e test.aab -o test.apk

在Mac上的使用,如下:
./aab2apk_mac -e test.aab -o test.apk

在Ubuntu上的使用,如下:
./aab2apk_linux -e test.aab -o test.apk

References#
- https://www.androidauthority.com/android-apks-sunset-1636829/
- https://conorlee.top/2019/03/27/Android-APP-Bundles-Introduction/
- https://developer.android.com/studio/build/index.html?hl=zh-cn#build-process
- https://zh.wikipedia.org/wiki/APK
- https://developer.android.com/topic/performance/reduce-apk-size?hl=zh-cn#apk-structure
- https://www.ifanr.com/1426594
- https://developer.android.google.cn/guide/app-bundle/app-bundle-format?hl=zh-cn


