APK科学瘦身

561 阅读5分钟

我报名参加金石计划1期挑战——瓜分10万奖池,这是我的第6篇文章,点击查看活动详情

前言

为什么叫科学瘦身,其实如果面试的时候问你,有做过APK瘦身吗?(一般应该也不会问得那么简单)。然后你说有,你就把别人总结的背给面试官,列举了十几个点。但其实并不是每个技术点都很重要,其实有些操作反而很鸡肋。我的意思是,你把apk的体积从100%压缩到70%甚至60%更低,这种叫瘦身。那你从60%压缩到59.9%也能叫瘦身,但是这操作意义不大,所以我觉得科学瘦身的含义在于,我们要做有用的瘦身,少做收益少的事。

收益小的瘦身操作

这里先抛出一个问题:简单来说,我们都知道资源在打包时是不进行压缩的,但是java代码,会编译成class文件,然后变成dex文件,这个过程是会压缩的。 那么,我写个资源shape资源,我直接用java代码写,相比于我用xml来写,理论上是不是瘦身?

没关系,做个实验,先用xml写个shape (为了方便就直接从网上随便拉个代码)

a54769586037f754c14de835837c22c.png

好,其实光一个文件,看不出什么,那我模拟现实,我写100个这样的xml(当然现实不止100个),但是我觉得100个足以模拟大部分的情况。

然后我用java来写这个shape,同样我写100个方法

31c2d98eece8cda28ff71672dd1e90b.png

然后分别打成apk包,来比较他们的大小。为了更直观,再请出1个参数选手,只写一个shape和两边的100个shape也进行个对比:

ee10e81a427c5f4132e05e0e1f7252c.png 可以很直观的看出,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的兼容情况

18550f276c216576dd190dd2af029d4.png

意思是假如你的手机是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,不错,拿来举例子很完美

14666ae53c05e34391558dcc727c370.png

还是老样子,一张说明不了问题,我这次弄了50张

2d84c293e87d6e7480fbe1834af8c78.png

然后我转成webp,同样的50张

d70826e32b1b61d9adf846ac9a0e132.png

分别打成apk,然后比较大小

38564227d950b7cd66805932870e899.png

这就有意思了,这应该也不用再做过多的解释,看一眼就能得出结论。

去除没用到的资源

这也是资源那方面的优化,没用上的资源要及时去除,你可以图个方便使用shrinkResources true,但我还是建议自己开发时,那些废弃的资源,及时拿掉。

不光是res的资源,assets的也是。

说到资源,又不得不提换肤,如果为了追求包体的大小,其中包含换肤功能,那建议使用动态换肤,静态换肤的话你会多额外的导入资源。但是这属于需求的方面,这种东西有舍有得。

总结

所以我认为在做APK瘦身的优化时,要把重心放在有收益的事情上,最能体现出效果的就是ABI的优化和资源的优化。

当然也还有一些东西会和需求相关,也是能从中省出很多的空间。比如你的项目大量的使用了帧动画,那能不能用Lottie去代替。比如你大量的本地视频,120帧的,改成60帧行不行?其实这些也是属于资源那块的优化。