1、为什么要对android包进行瘦身

(1)、包体积过大下载消耗的流量较多
(2)、会增加安装的时间

2、Apk的构成

ANDROID 引用zxing android 引用androidx后体积变大_编译过程


(1)、assets目录:存放需要打包到APK中的静态文件和res的不同点在于,assets目录支持任意深度的子目录,用户可以根据自己的需求任意部署文件夹架构,而且res目录下的文件会在.R文件中生成对应的资源ID,assets不会自动生成对应的ID。

(2)、lib目录:存放依赖的native库文件, 例如.so文件。

(3)、res目录:存放资源文件

(4)、resources.arsc文件:编译后的二进制资源文件

(5)、META-INF目录:保存应用签名信息,此处可验证APK的完整性,签名等。

(6)、AndroidManifest.xml:应件文件配置信息。

(7)、classes.dex:java,aidl文件生成的dex文件。

3、需要优化什么可以减小包的体积

我们可以根据apk的构成来对某个组成部分进行优化从而减小包的体积。

4、如何优化

(1)、对dex文件进行优化
android是运行在虚拟机上的,编译过程中会把java、aidl等文件编译成class,再转换成dex文件。可以删除一些无用的代码来减小dex文件的大小。

IDE会把未使用到的区块灰色展示,也可以通过lint工具来帮助我们识别到。这个功能在menu中的Analyze的Run inpection by name输入unused xx。甚至是在编译过程中,我们也可以通过混淆配置来做到,比方说常见的Log删除。

而随着业务发展,大型app都进行了模块化组件化,不同团队负责开发不同模块。开发过程极易出现一些重复工具方法,甚至引入相同功能的不同组件。架构上也需要一下规约工具来限定重复代码的编写。

在class转换成dex过程中,我们可以用新一代d8工具,它可以帮助我们的dex体积更小运行速度更快。Facebook也开源了一款redex的工具帮助优化dex。

classes.dex 中常量 R文件及内敛类的删除 * .R$ *
这都是些常量,那我们有没有办法删除这个文件呢,引用的地方直接使用常量的值?事实是可以的.
根据APK打包的编译过程,在编译过程中使用Android的Transform替换所有的类里面的常量. BuildConfig, Rlayout, R$string,AppConstans, etc
目前滴滴开源了一个booster 可以直接使用,不用在自己造轮子
booster-transform-shrink

(2)、对资源文件进行优化
选择体积更小的图片:例如webp格式的文件,我们知道Webp的压缩比例要比 png,jpg/jpeg的压缩比高,使用webp能减少一些包体积.要注意的是,webp在4.3以下有一些兼容问题,选择需谨慎。

对png也可以采用有损或无损压缩图片,常见工具有tingpng或imageoptim等。

小的icon也可以使用svg格式,一些特定效果也可以通过XML自定义实现。

国内应用除了应用的icon,大部分应用只设置了一套资源xh-dpi,所以推荐使用一套图片资源

当我们项目迭代不断迭代,总有些资源逐渐不在使用,成为了冗余,当很多时候又懒得删,或者怕删了出问题. Android Studio自带lint工具可以帮助我们清楚这些无用资源.

(3)、resources.ars优化
我们知道 res里面的资源文件名引用一般是这样的,例如将res/drawable/welcome.png那么打包的时候,是不是可以改成这样r/s/a.png.
事实是可以的,类似java的混淆规则去混淆资源,这样,所占用的字节数就会降低.
但是存在一个问题就是,这些资源资源ID已经被编译成32位int值,放入了resources.arsc.那么混淆的同时就要修改resources.arsc.
张绍文 tinker作者,前微信的技术大年,开源了AndResGuard,可以解决这样的方案,并且优化还可以.具体使用详解 AndResGuard

(4)、动态库优化

在一些需要安全高性能的常见,应用中需要采用native来实现。android平台提供了适配各种cpu架构的可能,包括x86 arm mips等,包活arm也有v7 v8等。针对不同cpu我们可以选择打不同包,gradle脚本中通过api也可以限制。或者损失一些性能,只采用arm最低版本也是可以兼容的。对于某些不常用功能,我们也能用动态加载,运行时再下载so到本地。

5、附录-名词解释

(1)、混淆规则(Proguard)
Android SDK自带了混淆工具Proguard。它位于SDK根目录\tools\proguard下面。
ProGuard是一个免费的Java类文件收缩,优化,混淆和预校验器。它可以检测并删除未使用的类,字段,方法和属性。它可以优化字节码,并删除未使用的指令。它可以将类、字段和方法使用短无意义的名称进行重命名。最后,预校验的Java6或针对Java MicroEdition的所述处理后的码。
如果开启了混淆,Proguard默认情况下会对所有代码,包括第三方包都进行混淆,可是有些代码或者第三方包是不能混淆的,这就需要我们手动编写混淆规则来保持不能被混淆的部分。

(2)、.9图片
9patch图片是andriod app开发里一种特殊的图片形式,文件的扩展名为:.9.png
9patch图片的作用就是在图片拉伸的时候保证其不会失真。所以我们使用.9图片,让图片在指定的位置拉伸和在指定的位置显示内容,这样图片的边边角角就不会出现失真了。

顶部:在水平拉伸的时候,保持其他位置不动,只在这个点的区域做无限的延伸(拷贝)

左边:在竖直拉伸的时候,保持其他位置不动,只在这个点的区域做无限的延伸(拷贝)

底部:在水平拉伸的时候,指定图片里的内容显示的区域

右边:在竖直拉伸的时候,指定图片里的内容显示的区域

ANDROID 引用zxing android 引用androidx后体积变大_android_02