DevYM Note

Do what you like is the most important thing !

APK瘦身过程记录

前言

记录开发成长过程中的点点滴滴,在探索的道路上从未止步,共勉!!!

随着项目不断壮大,在我们的日常开发中可能渐渐的会出现打出的apk文件越来越大的情况,这就导致在更新新版本的时候需要等待更久的时间,如果使用流量来更新的话就会损耗更多的流量(虽然现在无线流程套餐的土豪越来越多,但对于流量少的老铁多少会有点肉疼),所以APK的瘦身优化越来越重要

apk文件结构分析

我们将apk文件托到Android Studio 工具中(文雅点的方式:菜单栏 Build –>Analyze APK, 选择要分析的APK包)如下图:

  • lib文件夹:这个目录中存放着应用依赖的native库文件,这些以.so结尾的文件是用C或者C++语言编写的
  • classes.dex文件:classes.dex是java源码编译后生成的java字节码文件(首先是java文件通过jdk编译成字节码文件然后经过dex编译成classes.dex);
  • res文件夹:存放各种资源文件的目录;
  • resource.arsc文件: 编译后的二进制资源文件的索引,记录了资源文件(即res目录中的文件)和资源文件ID的映射关系,这样程序运行的时候就可以根据资源的ID获取到相应的资源了;
  • META-INF文件夹:存放的是签名信息,用来保证apk包的完整性和系统的安全;
  • AndroidManifest.xml文件:Android应用的配置清单文件,它向Android系统介绍了这个应用的很多配置信息,系统可以根据这个文件在相当程度上了解这个应用的一些信息;
  • assets文件夹:跟res目录有点相似,但assets中的文件则直接通过访问文件的地址来使用AssetManager类进行访问,而且assets目录你可以添加任意深度的子目录,这一点会比较方便管理和归类文件。

优化方案

从apk结构上来看,主要是lib、classes.dex、assets、res这几块占用比较大

1.lib中资源优化

lib这块的资源优化也就是对使用so文件的优化,很多第三方sdk的功能都是以so包的形式来接入的,为了支持不同指令集的情况,一般比较大众的第三方sdk都支持了armeabi、armeabi-v7a、arm64-v8a、x86、x86_64五种形式的so包,根据数据统计基本使用armeabi、armeabi-v7a两个目录就几乎可以兼容市面上绝大多数移动设备的cpu版本。因此我们在app的build.gradle文件中进行如下配置来进行优化:

1
2
3
4
// 配置so库架构(真机:arm, 模拟器:x86)
ndk{
abiFilters("armeabi","armeabi-v7a")
}

各个ABI版本对应的指令集可参照下图

2.减少classes.dex大小

单个的 classes.dex 文件可以容纳大约 64K 方法。如果你达到了这个限制,就会报65535错误,这个时候就需要采用一种分包的方式来进行编译。这将会创建另一个 classes1.dex 文件去存储剩下的方法。所以 classes.dex 文件数目由你的方法数而定。

  • 减少第三库的使用
    有些使用到第三方库的功能可能只是一小部分功能,这种时候引入这个第三方库付出的代价就有点高了,所以需要慎重使用
  • 避免使用枚举
    可以考虑使用@IntDef注释,这种类型转换保留了枚举的所有类型安全优势
  • 使用ProGuard
    代码混淆也是可以减小一部分classes.dex大小,这个可根据实际项目需要来优化,如果混淆后会对部分功能有影响可以优化混淆规则来使用

3.资源文件优化策略

  • 使用WebP文件格式
    在Android 3.2(API级别13)或更高级别时 ,可以使用WebP文件格式来制作图像,这种文件格式比PNG或JPEG文件更有优势,可以提供比JPEG或PNG更好的压缩。
    Android 4.0 (API level 14) 支持有损压缩的WebP格式,Android 4.3 (API level 18) 开始支持无损透明WebP图像。

Android Studio可以将PNG,JPG,BMP或静态GIF图像转换为WebP格式.使用方法可参照谷歌官方
Android Developers > Android Studio > User guide > 创建WebP图像的具体步骤,下面贴出一张转换前和转换后的对比图

1MB的图片转换后的大小为26.7KB,压缩后的效果跟压缩前几乎看不出有什么差异

  • 使用SVG矢量图

优势
1.占用存储空间小
2.无极拉伸不会出现锯齿,可以照顾不同尺寸的机型
3.Android Studio自带很多资源,减小UI工作量

缺陷

在谷歌官方文档中有介绍,矢量图首次加载时可能消耗更多的 CPU 资源,建议将矢量图像限制为最大 200 x 200 dp,否则,绘制它可能需要耗费很长的时间,所以不建议大尺寸图片使用

其实在我们新建一个app时也会发现res目录下会有一个mipmap-anydpi-v26文件夹下的默认图标使用的就是svg矢量图

  • 移除未使用的备用资源
    主要将对于国际化支持只打包中文资源
1
2
// 只保留指定和默认的资源
resConfigs("zh-rCN","ko")

参考:
android应用分析之apk文件结构
Android APK瘦身
你必须要懂的APK瘦身知识