前言
随着项目的发展,我们的 APK 会越来越大。这就意味着推广的成本会增加,用户在下载的时候会用掉更多的流量。上传应用市场的时候往往也会有大小的限制。如何为 APK 瘦身就成为迫在眉睫的任务。这篇文章总结了为 APK 瘦身的一些经验。
APK 的结构
标准的 APK 的目录中包含以下文件
classes.dex – 是 java 源码编译后生成的 java 字节码文件
resources.arsc – 编译后的二进制资源文件
AndroidManifest.xml – 每个应用都必须定义和包含的,它描述了应用的名字、版本、权限、引用的库文件等等信息
assets – 存放一些配置文件(比如 webview 本地资源、图片资源等等),这些文件的内容在程序运行过程中可以通过相关的 API 获得。
META-INF – META-INF目录下存放的是签名信息,用来保证apk包的完整性和系统的安全。
lib – 存放第三方库文件,lib 目录下的子目录 armeabi 存放的是一些 so 文件
res – 存放资源文件。包括图片、字符串、 raw 文件夹下面的音频文件、各种xml文件等等。
决定 APK 大小的主要是 classes.dex 、lib 和 res。
对 classes.dex 的优化通过代码混淆,删掉不必要的 jar 包和代码这里不做详细的介绍。这里主要介绍减小 lib 和 res 的方法。
优化 res
在 res 中主要存放的是一些资源文件,比如图片等等。对 res 的优化主要有:
优化 lib
一个硬件设备对应一个架构(mips、arm 或者 x86),只保留与设备架构相关的库文件夹,可以大大降低 lib 文件夹的大小。笔者发现,无论是 mips 还是 x86 架构的手机都支持 arm 的 so。所以我们可以只保留 arm 的 so。我们需要在项目的 build.gradle 中加入如下配置,就可以使其他架构的手机支持 arm 的 so。
defaultConfig {
multiDexEnabled = true
ndk {
abiFilters "armeabi", "armeabi-v7a"
}
}
这样配置以后,在打包的时候回自动过滤掉除了 armeabi 和 armeabi-v7a 之外的架构的 so,并在运行的时候运行 arm 的 so。
结语
笔者在开发过程中遇到的问题是引用的第三方库太多。而每个库都要支持不同的架构,这就导致 so 文件的体积快速增长,从而 APK 的体积也迅速变大。使用上述配置之后,把其他的架构的 so 删除,从而使 APK 的大小减了下来。