我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第6篇文章,点击查看活动详情
前言
为什么叫科学瘦身,其实如果面试的时候问你,有做过APK瘦身吗?(一般应该也不会问得那么简单)。然后你说有,你就把别人总结的背给面试官,列举了十几个点。但其实并不是每个技术点都很重要,其实有些操作反而很鸡肋。我的意思是,你把apk的体积从100%压缩到70%甚至60%更低,这种叫瘦身。那你从60%压缩到59.9%也能叫瘦身,但是这操作意义不大,所以我觉得科学瘦身的含义在于,我们要做有用的瘦身,少做收益少的事。
收益小的瘦身操作
这里先抛出一个问题:简单来说,我们都知道资源在打包时是不进行压缩的,但是java代码,会编译成class文件,然后变成dex文件,这个过程是会压缩的。 那么,我写个资源shape资源,我直接用java代码写,相比于我用xml来写,理论上是不是瘦身?
没关系,做个实验,先用xml写个shape (为了方便就直接从网上随便拉个代码)
好,其实光一个文件,看不出什么,那我模拟现实,我写100个这样的xml(当然现实不止100个),但是我觉得100个足以模拟大部分的情况。
然后我用java来写这个shape,同样我写100个方法
然后分别打成apk包,来比较他们的大小。为了更直观,再请出1个参数选手,只写一个shape和两边的100个shape也进行个对比:
可以很直观的看出,100个的情况下,相差并不大。反而如果你全部用Java来写,还会导致你在layout中没办法直接静态设置资源,还得在Java代码中去设置。那这样是不是反而得不偿失。
我之前在网上看过一些APK瘦身的文章,其中有人就讲过这样的一个知识点。 但其实效果好不好,可想而知,有的人会觉得关于《APK瘦身》这个话题,我能讲出的技术点越多,越牛逼。但做开发的还是要实事求是,不能光看别人怎么说,就觉得是对的,关键还要自己去实践。
收益最大的操作
正常的apk,占空间最大的是什么?你可以把apk拉到AS里面双击看看,你会发现占空间最大的是so文件。所以我们收益最大的搜身操作是对ABI的优化
什么是ABI
就是你libs下的armeabi、armeabi-v7a、arm64-v8a、x86、x86_64这些文件夹。ABI全称Application binary interface(应用程序二进制接口)
以前我写过一篇文章,感兴趣的可以去看看 www.jianshu.com/p/f43a423e7…
我这里就简单用一张图来表示ABI的兼容情况
意思是假如你的手机是ARMv7的,比如我这里有台华为ARMv7的,如果你在jniLibs只有个目录是x86的,那就可能会报错,因为我手机不会去加载这个目录的文件,它只支持armeabi和armeabi-v7a。现在市场上大部分都是ARMv7的,其实现在基本用armeabi的就够用了。
意思就是我们导入so文件时,打包的时候,可以把除了armeabi之外的文件夹都删除,这样能省去大量的空间。除非你有一些特殊的情况,需要使用某个ABI,你再加上。
尽量少使用第三方库的优势也体现在这里,假如你有用到一个复合型的三方库,假设它包含A、B、C三个功能,你只用到A,而B和C的功能它又依赖于Native方法,这样就导入了你不需要使用到的so文件,不就白白的占用空间了吗。
资源也是优化点
除了ABI之外,资源也占用了很大的空间,除非你代码多资源少,否则一般都是资源占整个包的第二比重。那怎么优化资源呢。
目前最主流的是把图片格式改成webp,还有部分相似度很高的图片,能用.9就用.9。
有的人可能会说,哎哟,这webp相比png也差不了多少,我这需求这么多,每次都要换很麻烦,鼠标点点点的,打断我敲代码的节奏,没那个必要。真的是这样的吗? 我们再做个实验
首先随便去网上找一张图,就这张吧,1.43MB,不错,拿来举例子很完美
还是老样子,一张说明不了问题,我这次弄了50张
然后我转成webp,同样的50张
分别打成apk,然后比较大小
这就有意思了,这应该也不用再做过多的解释,看一眼就能得出结论。
去除没用到的资源
这也是资源那方面的优化,没用上的资源要及时去除,你可以图个方便使用shrinkResources true,但我还是建议自己开发时,那些废弃的资源,及时拿掉。
不光是res的资源,assets的也是。
说到资源,又不得不提换肤,如果为了追求包体的大小,其中包含换肤功能,那建议使用动态换肤,静态换肤的话你会多额外的导入资源。但是这属于需求的方面,这种东西有舍有得。
总结
所以我认为在做APK瘦身的优化时,要把重心放在有收益的事情上,最能体现出效果的就是ABI的优化和资源的优化。
当然也还有一些东西会和需求相关,也是能从中省出很多的空间。比如你的项目大量的使用了帧动画,那能不能用Lottie去代替。比如你大量的本地视频,120帧的,改成60帧行不行?其实这些也是属于资源那块的优化。