草庐IT

Android aab转apk还原aab超过150MB 解决方案

xq9527 2023-03-28 原文

前言:

各位同学的大家好,最近要上架google 遇到的一些问题 所以整理一下。这个解决方案是37互娱的同学提供的我也只是重新整理下 希望大家不要说我抄袭

背景

当前海外主要渠道是谷歌的Google Play,而根据Google Play的政策,2021年8月起,就需要使用Android App Bundle(aab)格式了。
而且谷歌对包体大小也做了限制,超过150MB的包无法上传,如果只上传小包,那么玩家在进入游戏时必然需要等待较长时间的游戏资源加载,影响转化。而如果想在安装时就附带游戏资源,突破150MB的限制,则需要接入谷歌提供的Play Asset Delivery功能。
更多的介绍可以回顾我们之前的文章。
Android apk和aab互相转换

问题

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

基本思路

我们先看看旧的针对APK的切包流程
这个流程里面最核心的是融合代码的过程,里面是包含了许多前辈的(工时)心血的,我们肯定不希望(加班)重新再写一次,如果能复用这部分的代码就好了。
那么怎样才能最大限度的利用已有的功能呢?

如果我们能够先把aab转成apk,那样就可以完全复用旧的逻辑,等到apk切包成功后,我们再将apk转回aab,岂不是完美?新的流程如下
那按计划,我们只需要做两件事情:

把研发输出的aab+pad转成apk

把切包后的apk转成aab+pad

计划很完美,接下来只需要按计划行事
aab+pad转apk
接入了pad的aab格式
首先我们先了解下aab+pad的文件组成,单纯的aab格式可以参考之前的文章政策工具类-谷歌Android App Bundle(aab)政策海外发行,而当接入了pad后,aab内的文件又会怎样呢?
按官方文档Android App Bundle 格式的介绍,pad的资源包是存在区别于主体代码文件夹(base/)的独立文件夹内的。
上图中紫色的部分就是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/
image.png

复制代码

其中base/,BundleConfig.pb,META-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

直接转命令

java -jar bundletool-all-1.6.1.jar build-apks \
--mode=universal \
--bundle=base.aab \
--output=test.apks \
--ks=luojian37.jks \
--ks-pass=pass:****** \
--ks-key-alias=****** \
--key-pass=pass:******

里面只有两个文件,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+pad中提取pad压缩包
把研发输出的aab+pad转成apk
把切包后的apk转成base压缩包
把base压缩包和pad压缩包转化aab包

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

├── base/
    ├── dex/
    ├── .../
├── base_assets/
    ├── assets/
    ├── assets.pb
    ├── manifest/
        ├── AndroidManifest.xml
├── BundleConfig.pb
├── META-INF/

其中base_assets/目录就是pad资源,在它里面
assets/目录,一般就是游戏的资源,会直接合并到apk的assets中,保留。
assets.pb,pb文件是配置信息文件,由bundletool生成,压缩包内不需要,直接删除。
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,所以只需要执行到压缩资源这一步即可。
这里我们还是讲一下那个脚本怎么生成的 因为手动很多人也不愿意去动
我们找到 bundletool.py 文件


image.png

然后把这里delete操作注释起来


image.png

在build_aab_tool\temp_20220621151158\modules 目录下面会有这个base.zip
image.png

细心的朋友应该已经发现,这里使用的apk包还是和之前一样,是包含了pad资源的,但是现在pad的内容在之前已经被压缩到pad.zip中了,所以如果还是全量资源放进base.zip中,那么在转换aab,合并base.zip和pad.zip时就会出现资源冲突的问题。
所以我们需要在编译资源前,把pad中的资源从apk的反编译目录中移除掉,所以我们得到的base.zip是不包含pad资源的。
  • 0x04 产出包含pad的aab

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

java -jar bundletool-all-1.6.1.jar build-bundle --modules=base.zip,install_time_asset_pack.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的切包流程的分析过程,以及所需要注意的细节,再次感谢37互娱的同学提供方案,我也是做个整理。希望文章能帮助到各位同学。以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里

有关Android aab转apk还原aab超过150MB 解决方案的更多相关文章

  1. ruby - 在 jRuby 中使用 'fork' 生成进程的替代方案? - 2

    在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',

  2. 屏幕录制为什么没声音?检查这2项,轻松解决 - 2

    相信很多人在录制视频的时候都会遇到各种各样的问题,比如录制的视频没有声音。屏幕录制为什么没声音?今天小编就和大家分享一下如何录制音画同步视频的具体操作方法。如果你有录制的视频没有声音,你可以试试这个方法。 一、检查是否打开电脑系统声音相信很多小伙伴在录制视频后会发现录制的视频没有声音,屏幕录制为什么没声音?如果当时没有打开音频录制,则录制好的视频是没有声音的。因此,建议在录制前进行检查。屏幕上没有声音,很可能是因为你的电脑系统的声音被禁止了。您只需打开电脑系统的声音,即可录制音频和图画同步视频。操作方法:步骤1:点击电脑屏幕右下侧的“小喇叭”图案,在上方的选项中,选择“声音”。 步骤2:在“声

  3. 【高数】用拉格朗日中值定理解决极限问题 - 2

    首先回顾一下拉格朗日定理的内容:函数f(x)是在闭区间[a,b]上连续、开区间(a,b)上可导的函数,那么至少存在一个,使得:通过这个表达式我们可以知道,f(x)是函数的主体,a和b可以看作是主体函数f(x)中所取的两个值。那么可以有,  也就意味着我们可以用来替换 这种替换可以用在求某些多项式差的极限中。方法: 外层函数f(x)是一致的,并且h(x)和g(x)是等价无穷小。此时,利用拉格朗日定理,将原式替换为 ,再进行求解,往往会省去复合函数求极限的很多麻烦。使用要注意:1.要先找到主体函数f(x),即外层函数必须相同。2.f(x)找到后,复合部分是等价无穷小。3.要满足作差的形式。如果是加

  4. 深度学习部署:Windows安装pycocotools报错解决方法 - 2

    深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. Ruby 守护进程和 JRuby - 备选方案 - 2

    我有一个应用程序正在从Ruby迁移到JRuby(由于需要通过Java提供更好的Web服务安全支持)。我使用的gem之一是daemons创建后台作业。问题在于它使用fork+exec来创建后台进程,但这对JRuby来说是禁忌。那么-是否有用于创建后台作业的替代gem/wrapper?我目前的想法是只从shell脚本调用rake并让rake任务永远运行......提前致谢,克里斯。更新我们目前正在使用几个与Java线程相关的包装器,即https://github.com/jmettraux/rufus-scheduler和https://github.com/philostler/acts

  7. ruby - 如何更快地解决 project euler #21? - 2

    原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,

  8. ruby - 为什么这些方法没有解决? - 2

    这个问题在这里已经有了答案:WhydoRubysettersneed"self."qualificationwithintheclass?(3个答案)关闭29天前。给定这段代码:classSomethingattr_accessor:my_variabledefinitialize@my_variable=0enddeffoomy_variable=my_variable+3endends=Something.news.foo我收到这个错误:test.rb:9:in`foo':undefinedmethod`+'fornil:NilClass(NoMethodError)fromtes

  9. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  10. 关于Qt程序打包后运行库依赖的常见问题分析及解决方法 - 2

    目录一.大致如下常见问题:(1)找不到程序所依赖的Qt库version`Qt_5'notfound(requiredby(2)CouldnotLoadtheQtplatformplugin"xcb"in""eventhoughitwasfound(3)打包到在不同的linux系统下,或者打包到高版本的相同系统下,运行程序时,直接提示段错误即segmentationfault,或者Illegalinstruction(coredumped)非法指令(4)ldd应用程序或者库,查看运行所依赖的库时,直接报段错误二.问题逐个分析,得出解决方法:(1)找不到程序所依赖的Qt库version`Qt_5'

随机推荐