政策工具类-谷歌Android App Bundle(aab)+Play Asset Delivery(pad)发行切包

作者

大家好,我是加权,目前负责海外游戏发行的安卓开发。

背景

当前海外主要渠道是谷歌的Google Play,而根据Google Play的政策,2021年8月起,就需要使用Android App Bundle(aab)格式了。

而且谷歌对包体大小也做了限制,超过150MB的包无法上传,如果只上传小包,那么玩家在进入游戏时必然需要等待较长时间的游戏资源加载,影响转化。而如果想在安装时就附带游戏资源,突破150MB的限制,则需要接入谷歌提供的Play Asset Delivery功能。

更多的介绍可以回顾我们之前的文章。

  1. 政策工具类-谷歌Android App Bundle(aab)政策海外发行
  2. 政策工具类-apk转aab+pad

问题

根据上述背景,海外游戏使用aab+pad的搭配必然是大势所趋了。而当研发接入pad功能后,就只能产出aab包了,因为pad是依赖于aab格式的。而旧有的切包流程是针对apk包的,不再适用于当前业务了,所以我们要怎样对aab+pad包进行切包,升级sdk代码?且看下文分解。

基本思路

我们先看看旧的针对APK的切包流程

APK切包流程.jpg
这个流程里面最核心的是融合代码的过程,里面是包含了许多前辈的(工时)心血的,我们肯定不希望(加班)重新再写一次,如果能复用这部分的代码就好了。

那么怎样才能最大限度的利用已有的功能呢?

如果我们能够先把aab转成apk,那样就可以完全复用旧的逻辑,等到apk切包成功后,我们再将apk转回aab,岂不是完美?新的流程如下

AAB切包流程
那按计划,我们只需要做两件事情:

  1. 把研发输出的aab+pad转成apk
  2. 把切包后的apk转成aab+pad

计划很完美,接下来只需要按计划行事~

aab+pad转apk

接入了pad的aab格式

首先我们先了解下aab+pad的文件组成,单纯的aab格式可以参考之前的文章政策工具类-谷歌Android App Bundle(aab)政策海外发行,而当接入了pad后,aab内的文件又会怎样呢?

按官方文档Android App Bundle 格式的介绍,pad的资源包是存在区别于主体代码文件夹(base/)的独立文件夹内的。

Android App Bundle 格式
上图中紫色的部分就是pad的资源包。

  • asset_pack_1/ 和 asset_pack_2/ :对于需要大量图形处理的大型应用或游戏,您可以将资产模块化处理为资源包。……如需详细了解如何将资源包添加到您的 app bundle,请参阅 Play Asset Delivery 概览

百闻不如一见,有了理论基础,我们直接找个aab+pad的包解压看看~
解压某个接入了pad的游戏的aab包,我们得到了

├── base/

    ├── dex/

    ├── .../

├── base_assets/

    ├── assets/

    ├── assets.pb

    ├── manifest/

        ├── AndroidManifest.xml

├── BundleConfig.pb

├── META-INF/

其中base/BundleConfig.pbMETA-INF/都是老熟人了,那么毫无疑问,剩下的base_assets/就是研发接入的pad资源包了,实际上这个文件夹的名称取决于研发接入时的文件夹名称,是可变,我们在切包时需要考虑这个因素

aab转apks

虽然计划是aab转apk,但是实际上aab并不能直接转apk,而是需要先转成apks文件。

处理aab文件,谷歌提供了一个专用的工具bundletool,详细的使用方法大家可以自行google,不再叙述。

那我们aab转apks自然也是要用到这个工具,具体是使用build-apks指令。

不过需要注意的是,aab转apks,一般情况是针对特定设备转换的,这时候不适用于该设备的资源就不会放进apks中,而我们的目的是进行切包,肯定是需要所有资源的,那么就需要用到build-apks指令的--mode=universal参数了,参数的具体含义和作用大家自行阅读文档。

所以完整指令是

java -jar bundletool.jar build-apks --mode=universal --bundle=my_app.aab --output=my_app.apks

然后我们就得到了一个apks文件。

apks转apk

apks实际上就是一个压缩包,可以直接解压,百闻不如一见,我们直接解压上述命令得到的apks文件看看,里面究竟有什么。

├── toc.pb
├── universal.apk

里面只有两个文件,toc.pb虽然我们不知道这是什么,但是pb文件一般都是提供配置信息,直接忽略,剩下的universal.apk文件就是我们需要的,包含了所有资源和代码的apk了。

拿到apk后,我们就可以使用旧流程进行切包,对apk内的代码进行升级了,之后我们就可以拿到切包后的apk文件。

至此,我们就按计划完成了第一步了,进度50%,一切顺利。?

apk转aab

更加顺利的是,apk转aab我们之前的文章政策工具类-谷歌Android App Bundle(aab)政策海外发行已经有所介绍,按照文章介绍,最后我们就可以得到了一个aab包。难道我们已经成功了吗?

先别高兴得太早,滚动条的位置已经透露了事情没有那么简单。

aab+pad切包,pad的功能才是关键,所以我们还需要验证pad功能是否正常,我们解压转换得到的aab包,就会发现,pad功能对应的文件夹(上文中的base_assets)消失了。那么这个文件夹是什么时候丢失的呢?

我们仔细想想,apk是不支持pad功能的,所以应该是在aab转apks时,bundletool把pad的资源也合并进apk中了,而在--mode=universal中也有相关描述

注意bundletool 仅包含功能模块,这些模块在通用 APK 中的对应清单中指定 <dist:fusing dist:include="true"/>。如需了解详情,请参阅功能模块清单

bundletool会把功能模块包含进apk中,所以pad在转换的过程当中已经被合并进apk了。这意味着得到的aab包是不包含pad功能的,那就不能突破150M的限制了,所以还是不能上传到谷歌后台。

问题分析

所以我们现在的问题是,apk转aab的时候,pad资源丢失了,那么我们能不能在apk转aab时,把pad资源补回来呢?

根据之前的文章,政策工具类-apk转aab+pad中的生成aab+pad的包部分,我们知道,只要我们能提供pad的资源压缩包,那么就可以把pad重新打进aab中,所以我们的流程图调整如下

aab切包流程2

问题不大,我们只需要稍微调整计划,把需要做的事情变为:

  1. 从研发输出的aab+pad中提取pad压缩包
  2. 把研发输出的aab+pad转成apk
  3. 把切包后的apk转成base压缩包
  4. 把base压缩包和pad压缩包转化aab包

0x01 提取pad压缩包

上文已经提到,接入了pad的aab包目录结构如下

├── base/

    ├── dex/

    ├── .../

├── base_assets/

    ├── assets/

    ├── assets.pb

    ├── manifest/

        ├── AndroidManifest.xml

├── BundleConfig.pb

├── META-INF/

其中base_assets/目录就是pad资源,在它里面

  1. assets/目录,一般就是游戏的资源,会直接合并到apk的assets中,保留。
  2. assets.pbpb文件是配置信息文件,由bundletool生成,压缩包内不需要,直接删除。
  3. manifest/AndroidManifest.xml,为pad编译后的配置信息,决定了pad的下发规则,我们不需要更改研发决定的pad下发规则,所以保留即可。

按上所述,我们直接把pad目录下的assets/manifest/压缩得到pad压缩包,留作后续步骤使用。压缩包的目录结构应如下

// pad.zip,名称随意,下文统一称pad.zip
├── assets/
├── manifest/
    ├── AndroidManifest.xml

0x02 aab+pad转成apk

和上文完全一致,不再重复。

0x03 apk转成base.zip

我们还是参考政策工具类-谷歌Android App Bundle(aab)政策海外发行, 不过这次我们只需要base.zip,所以只需要执行到压缩资源这一步即可。

细心的朋友应该已经发现,这里使用的apk包还是和之前一样,是包含了pad资源的,但是现在pad的内容在之前已经被压缩到pad.zip中了,所以如果还是全量资源放进base.zip中,那么在转换aab,合并base.zippad.zip时就会出现资源冲突的问题。

所以我们需要在编译资源前,把pad中的资源从apk的反编译目录中移除掉,所以我们得到的base.zip是不包含pad资源的。

0x04 产出包含pad的aab

最后,我们顺利得到包含主要代码的base.zip和包含pad资源的pad.zip,就可以通过以下命令输出aab了

java -jar bundletool.jar build-bundle --modules=base.zip,pad.zip --output=my.aab

如果一切顺利的话,那么我们就可以再次得到一个aab包,最后我们再次验证下有没有翻车。

验证

解压aab包可以发现pad的目录还存在,另外我们还可以

java -jar bundletool.jar validate --bundle my.aab

如果打包后pad正常,那么输出的结果中会包含以下内容(base_assets为pad模块的名称,不同游戏会不同)

Asset packs:
	Asset pack: base_assets

结束语

本文介绍了aab+pad的切包流程的分析过程,以及所需要注意的细节,希望能帮到大家~

过程中有问题或者需要交流的同学,可以扫描二维码加好友,然后进群进行问题和技术的交流等;

© 版权声明
THE END
喜欢就支持一下吧
点赞0

Warning: mysqli_query(): (HY000/3): Error writing file '/tmp/MYaXCMY0' (Errcode: 28 - No space left on device) in /www/wwwroot/583.cn/wp-includes/class-wpdb.php on line 2345
admin的头像-五八三
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

图形验证码
取消
昵称代码图片