APK大瘦身

APP性能优化

Posted by ChaserSheng on September 25, 2017

随着我们的APP迭代,安装包的体积也会跟着增大。 就拿我目前所开发维护的APP来讲,版本号20,APK大小是12M,金融类的应用。虽然功能也不少,但是因为是混合开发,这个大小相对来说是偏大的,应用太大不利于运营推广,并且浪费用户的流量,所以在APP的瘦身是很必要的。这片文章讲我的应用在APK瘦身中的一些经验方法,希望对你能有所帮助。

APK分析

我们来看下APK的构成,将你编译后的APK拖到AndroidStudio中,从AndroidStudio2.2版本开始我们可以使用APK Analyzer来分析APK,当然你也可以更改APK的后缀名为zip,解压之后可以看到APK的内容,如下图:

APK主要由一下几个部分组成

res:

主要存放一些图片资源和xml资源

lib:

存放各种架构的so库

classes.dex

java源码编译后生成的java字节码文件,由于超过了Android最大方法数限制,这里拆分了多个dex文件

assets

主要存放一些不需要编译处理的文件,比如我们常常为了加快WebView的访问速度,会把一些框架性不常更改的js、css和一些png等图片资源放在这里面

resources.arsc

编译后的二进制资源文件,包括图片、文本索引等

META-INF

应用签名信息

AndroidManifest.xml

描述配置文件

从图片中我们看到占比较大的几个,对其进行分析优化。

优化方式1-资源优化

图片资源压缩-res文件夹下

1.TinyPng

可以拖拽图片到网页上处理,同时提供HTTP api来处理,有数量限制,每个key每个月限500张。网上也有相关的Gradle插件来批量处理,我的项目中使用的就是这种图片压缩方式,压缩效果因图片而异,我的项目中的图片大小减小了一半左右。Mac下或者安装了Python环境的同学可以试一下这个批量压缩的脚本GcsSloop/TinyPng

2.ImageOptions

提供客户端,未使用过,具体请移步官网

需要说明的是这里的压缩虽然最大程度的保留了图片的质量,优化修改了png的一些属性等,但是对于图片质量还是有一些影响的,特别是在一些高清大图。

移除无用资源

有时候我们移除某一项功能的时候,并没有移除相应的资源文件,如果不做处理,这部分资源文件很有可能打包到我们的apk中,产生空间浪费。

1.使用AndroidStudio自带的Lint检查无用资源,然后通过脚本批量移除;

2.使用Gradle的shrinkResources在打包的时候移除未使用资源;

3.官方推荐我们在不同分辨率对应的文件夹下放置对应的资源图片,ldpi mdpi hdpi xhdpi xxhdpi xxxhdp等,但是这样做的话会极大的增加包的体积,一般来说我们只需要两三套就可以了,我现在是使用的一套图片资源,现阶段可以只保留xhdpi下的图片,关于为什么官方推荐需要多套资源图片,请自省百度,这也是个很重要的知识点;

减少多语言支持

我们的APK默认打包出来支持几十种语言,这显然是不必要,我这里只保留简体中文,当然如果你的APP在繁体中文或者海外也有推广运营的话,请保留需要的语言,这种方式能减少几百k的大小。

defaultConfig {
        resConfigs "zh"
}
资源混淆方案

我记得以前刚学反编译apk的时候,尝试反编译微信的APK,但是反编译后发现xml文件都是a、b、c这种命名,觉得很神奇。后来才知道,这是微信自己开发的资源混淆方式,原理是把冗长的资源路径变短。详情请见AndResGuard。通过这种方式我把APK又减小了0.8M。但是有一点请注意,一些通过反射获得的资源或者是某些三方库中的资源需要加入白名单,要多加测试,避免出错。

lib文件夹

1.CPU架构支持

Android目前支持的架构多达七种,每一种架构对应一种ABI:armeabi,armeabi-v7a,x86,mips,arm64-v8a,mips64,x86_64。所有的x86、x8664、armeabi-v7a、arm64-v8a设备都支持armeabi架构的.so文件,x86设备能够很好的运行ARM类型函数库,但并不保证100%不发生crash,特别是对旧设备。64位设备(arm64-v8a, x8664, mips64)能够运行32位的函数库,但是以32位模式运行,在64位平台上运行32位版本的ART和Android组件,将丢失专为64位优化过的性能(ART,webview,media等等)。一般的应用完全可以根据自己业务需求选择使用armeabi或者armeabi-v7a一种支持就行。

ndk {
      abiFilters 'armeabi'
}

2.动态下发

so文件可以通过动态下发的方式延迟加载,网络上有文章这么做过,我这里没用过不做说明。

dex文件

1.Gradle中设置minifyEnabled true混淆、压缩代码

2.删除一些无用库,包括一些早期的兼容库,删除一些非必需的三方库,或使用轻量级的替代库

3.插件化开发,通过下发的方式减小APP体积

其它方式

1.Proguard不保留行号信息,但是这种方式会不利于我们查找线上bug日志

2.facebook的ReDex,需要多测试

… …

我们常见的APK瘦身方法就讲完了,如果你有更多更好的方式请告诉我,当然,这都是现阶段的优化方法,随着Android的进步我们肯定会有更多的方法。