文章目录
前言
Google在2021年的8月份起,要求所有上架Google Play的应用必须采用.aab的新格式才可以上传应用包,对于aab新格式的包其实早在去年的年底官方就做了对应的通知了,不过aab虽然首次出现的时间是在2018年,但是在国内很少被提及到,基本上都是以apk为主,现在既然Google强制要求使用aab来上架GP(Google Play),那么这篇文章就来讲讲aab和apk的区别~
一、aab是什么?
Android App Bundle(简称aab),是Google 2018年首次推出的一种动态化的打包方式,主要的呈现形式表现在当开发者以aab的格式把应用上传到GP,GP可以根据不用的用户来实现Features或者 Resources 的按需下发;
- Play Feature Delivery(PFD):借助aab实现Feature的按需动态加载,就类似于国内现在流行的插件化技术。
- Play Asset Delivery (PAD):借助aab实现一些素材资源的按需下载,这就比较适合游戏类的App了,无需为了适配所有的机型而保留所有的游戏素材。但是对于常规的App来说,也是可以一样做到按需下发的,例如可以无需同事存在hdpi、xhdpi 等多套图片,这样也可以减小应用包的体积大小。
二、aab和apk的区别
1.aab和apk的文件格式
首先先来看两张图,看看aab和apk的文件格式有什么具体的变化,图1是aab,其次是apk
至于apk的文件格式我就不必多说了,相信大家做Android开发的应该都知道,现在说说aab的文件格式,整理了一个表格:
文件 | 具体描述 |
---|---|
assets目录 | 用于放置APP所需的固定文件,且该文件被打包到APK中时,不会被编码到二进制文件 |
lib目录 | 主要放so文件,上传aab时,GP会检查这些目录并仅仅打包满足目标设备所需的最小文件 |
dex目录 | 编程的时候是java文件,但是Android并不能直接运行java文件,所以在生成apk或者aab的时候会先把java文件转换成class文件,最后在转换成可运行在Android上面的dex文件 |
res目录 | 主要资源文件,icon、图片及布局等文件 |
resources.pb | 类似于 resource.arsc 文件,是一个资源索引表,其中描述了应用程序内部存在的资源和目标的细节,可用于 GP 针对不同设备配置 APK |
res目录 | 主要资源文件,icon、图片及布局等文件 |
manifest目录 | 主要放置Android的清单文件 |
assets.pb | 这个文件有点类似于应用程序的assets资源表,主要是GP针对不同的设备配置Apk |
native.pb | 相当于native库的资源表,主要还是用于 GP 针对不同设备配置 APK |
2.Split APKs
Split APKs 机制是 AAB 实现动态下发的基础,它允许将一个庞大的 APK 按不同维度拆分成独立的 APK,当用户在 GP 下载应用时,Android Framework 通过 IPC 与 GP 通信,为当前设备匹配并下载最小构成的 APK, 但是需要注意的是,这只在 Android 5.0 以上的设备才有效,对于Android 5.0以下的设备,aab会根据Splits的矩阵生成多个Standalone的Apk,就是为了适配Android 5.0以下的多种设备;
aab文件的应用不能直接安装到Android设备上,所以我们这里要把aab转成apks,然后才可以正常的安装到设备上,这里会介绍到官方提供的一个工具:Bundletool
3.Bundletool的使用
介绍Bundletool之前,我们首先需要知道aab是如何生成的,这里可以直接build个debug的aab包
生成的路径如下:
这个aab包是不带签名的,这里也可以直接生成带签名aab包
框框的地方可以勾选,到时候会生成一个 .pepk文件,这个文件到时候上传到GP会用到,然后next就可以生成一个带签名的aab包了,那aab包已经有了,怎么转成Apks呢,这里就要使用到Bundletool了:
首先先下载一个bundletool工具,下载地址,当 bundletool 从 app bundle 生成 APK 时,它会将这些 APK 纳入到一个名为“APK set archive”的容器中,该容器以 .apks 作为文件扩展名。这里的话主要是bundletool使用对应的命令来生成Apks。
java -jar bundletool-all-1.7.0.jar build-apks
--bundle=app-debug.aab
--output==app.apks
--ks=hw.jks
--ks-pass=pass:123456
--ks-key-alias=123456
--key-pass=pass:123456
标记 | 说明 |
---|---|
- -bundle=path | 指定使用 Android Studio 构建的 App Bundle 的路径,也就是生成的aab的具体路径 |
- -output=path | 指定“.apks”输出文件的名称,该文件中包含了应用的所有 APK 工件 |
- -ks=path | 指定用于为 APK 签名的部署密钥库的路径。此标记是可选的,如果不添加此标记,bundletool 会尝试使用调试签名密钥为你的 APK 签名 |
- -ks-pass=path | 指定密钥库的密码,如果指定纯文本格式的密码,使用 pass: 限定该密码,如果要传递包含该密码的文件的路径,请使用 file: 限定该路径 |
- -ks-key-alias=path | 指定要使用的签名密钥的别名 |
- -output=path | 指定秘钥库的密码 |
生成一组 APK 后,bundletool 可以将其中适当的 APK 组合部署到已连接的设备,如果是android 5.0(API 级别 21)以上的设备,BundleTool会在该设备上安装所需的基础Apk、功能模块Apk和配置Apk,但是如果是低于Android 5.0的设备,那BundleTool会查找更多兼容的Apk安装到对应的设备上。
用命令行进行安装apks:
java -jar bundletool-all-1.7.0.jar install-apks --apks=app.apks
总结
总得来说,Android App Bundle 是一种发布格式,其中包含您应用的所有经过编译的代码和资源,它会将 APK 生成及签名交由 Google Play 来完成,但是这里有个值得一提的地方,aab的文件大小一般会比apk小20%左右,但是有时候生成的Apks文件大小却会比原来的大好几十倍,这时因为build.gradle文件中minSdkVersion 小于21的原因,BundleTool就会生成很多歌兼容Android 5.0以下设备的Apk,如下图所示
如果不想生成过大的apks文件,只需要把minSdkVersion改成大于等于21就行了;
参考文章链接:https://juejin.cn/post/6984588418554527774#heading-6