在很久很久的塞班时代,那时候的程序几十KB就算大了。
在不久的几年前,很多APP也是几M大小。
不过到了最近几年,都是几十M的。
你看那微信,支付宝,滴滴打车,都是50M差不多大小的巨兽
对于要压缩我们的apk大小,需要一些指导的思想,告诉我们往哪里找空间
这张图片告诉我们一个方向
- 压缩项目代码量,删除过时没用的
- 降低我们的资源文件大小,例如图片,用混淆等
- 下载的第三方库和so等文件尝试用更小的
- 一些assets的内容不用的移除
1.去除多余的类
对于一些包,可能只用到了几个方法,可以尝试用别的更小的包代替,或者直接抽出来那几个方法来用。
关于计算方法,这里有一个相对好用的方法推荐dexcount-gradle-plugin
。
在你的app/build.gradle添加
dependencies {
classpath 'com.getkeepsafe.dexcount:dexcount-gradle-plugin:0.3.0'
}
apply plugin: 'com.getkeepsafe.dexcount'
接着打开在AS底部的Terminal,输入下面的命令
> gradlew assembleDebug
在结尾的地方,就会
。。。
Total methods in app-debug.apk: 50020 (76.33% used)
Total fields in app-debug.apk: 31868 (48.63% used)
Methods remaining in app-debug.apk: 15515
Fields remaining in app-debug.apk: 33667
BUILD SUCCESSFUL
除此之外,还提供一些图形化的界面可以查看,路径在:${buildDir}/outputs/dexcount/
或者我们打开目录里面的这个debugChart/index.html
文件
这时候可以很方便的看到具体那个包的方法数,不过好像看不了大小
更多内容可以看官方文档https://github.com/KeepSafe/dexcount-gradle-plugin
如果可以,可以手动精简一些包,很多功能都没用到。
例如当年的volley,他的工具包里面例如图片加载等很多就没使用到,这完全就浪费啊。
2.降低版本
compile 'com.android.support:appcompat-v7
compile 'com.android.support:appcompat-v4
这两个包V24.0.0版的1.4M左右,版本越高的V7和V4,包越大。如果是非常小的项目,完全没有必要引用它俩。
或者可以考录用低版本的,虽然新版本可能修复一些bug,例如RecycleView曾经就有过分割线的显示错误问题。
在这里推荐一个叫MethodCount的插件,他可以帮助我们快速的查看我们添加的包的方法数目,这个包的额外依赖的包的数目,同时点击蓝色的圈,可以查看具体的依赖的内容!
例如我们的appcompat-v7-23.1.1,点击它查看各个版本依赖的内容。
这里看到我们的23.1.1是有5319个方法,额外依赖2个,Design包就是2165个方法,4个额外的依赖。
通过这个,可以提供实际的数据,指导我们做判断。
这个就比那个dexcount
来个更快和直接,不过它不可以看自己的包代码效果,和编译后的情况,各有特色。
3. 混淆
使用proguard混淆代码,它会对不用的代码做优化,并且混淆后也能够减少安装包的大小。
buildTypes {
release {
minifyEnabled true // <-开启
shrinkResources false
zipAlignEnabled true
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
对release版本用混淆可以很好的减少大小,因为他会将没用的剔除掉
4. 去除X86.so
native code的部分,大多数情况下只需要支持armabi与x86的架构即可。如果非必须,可以考虑拿掉x86的部分。
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
minSdkVersion 19
targetSdkVersion 23
multiDexEnabled false
ndk {
//这个配置让realm数据库只有armeabi.so文件,从而压缩apk的大小
abiFilters "armeabi" //就是这句,可以有效减少大小!你去看微信它也是只有支持armeabi了。
}
}
5. 去除没用的资源
随着发展,很多图片等资源都不用了,甚至一些font也不再使用,这时候应该考虑删除掉。
为了一次性的移除没用的资源,这是我们可以使用到的,使用Lint工具
查找没有使用到的资源。
位置在顶部的 Refactor-> Inspect Code
.然后清楚没用的资源
很多项目组做到一定程度,都会自定义出一份自己的Lint配置项。
或者自己公司的代码风格等内容。
关于如何自定义LINT,可以看这个美团的案例:Android自定义Lint实践
关于代码风格问题,具体查看这个地址checkstyle-idea
个人是建议统一代码风格的,这有助于我们统一代码,避免“巴别塔之乱”这样的故事
除此还有微信出版的一个强效工具AndResGuard,具体文章介绍看这里安装包立减1M–微信Android资源混淆打包工具
图片
大图化小,小图化了
6. 图片格式
微信对图片从PNG替换成SVG
,整体大小达到了压缩,具体文件可以查看这里
另外还有webP图片格式
也是可以参考的,现在不少公司都开始用了。
对于图片压缩
也是一个不错的方式,tinypng用其独特的算法可以实现在无损压缩的情况下图片文件大小缩小到原来的30%-50%。
这个压缩图片是强烈推荐的,可以让你的XXX-hdpi的减少个几M都是有可能的!!!
7. 降低依赖包的图片资源
覆盖aar里的一些默认的大图,一些aar库里面包含我们没用到的图,语言版本等。
最典型的是support-v4兼容库中包含一些“可能”用到的图片,实际上在你的app中不会用到。
可以在/build/intermediates/exploded-aar/下的各个aar库的res目录查找检验。然后删除!
8. 插件化
关于插件化,这个目前已经有很成熟的技术方案了,不过对一部分业务不大的程序,估计效果一般。
对于像支付宝,淘宝之流的就效果明显!
当然,或许可以考录砍功能 ,虽然一般程序都是上功能容易,砍一个就相对难,或者PM根本就没想过要删哪一个。
9.Facebook的redex优化字节码
redex是facebook发布的一款android字节码的优化工具,需要按照说明文档自行配置一下。
redex input.apk -o output.apk --sign -s <KEYSTORE> -a <KEYALIAS> -p <KEYPASS>
如果先进行redex,在进行微信混淆,减小了711k,redex贡献了157k:
另外,据反应redex后会有崩溃的现象,这个要留意一下,我这里压缩之后都是可以正常运行的。
详情参考:ReDex: An Android Bytecode Optimizer
极限压缩
apk实质是一个zip压缩包,在zip压缩包里有两种模式:Deflate
和Stored
Deflate是抽气,压缩的意思,跟LayoutInflater里的inflate是相反的单词,inflate是填充,充气的意思。
可以看出resources.arsc、*.png采用压缩模式,而其它采用存储模式。
如何极限压缩?把Stored模式的变为Deflate模式。
选择压缩算法
压缩算法 | 文件大小(kb) |
---|---|
普通Zip-普通压缩 | 20016 |
普通Zip-极限压缩 | 20012 |
7zZip-普通压缩 | 19800 |
7zZip-极限压缩 | 19578 |
从表格中我们知道7zZip的压缩效果比普通Zip好,并且7zZip-极限压缩的比普通压缩要好,因此为了极限压缩,我们采用7zZip-极限压缩。
注意:
在Android2.3以前的任何压缩的资源的原始大小超过1M,AssetManger读取时会抛出异常。
流媒体文件不能进行压缩
限制:只支持2.3以上版本程序才可以使用
因此极限压缩的极限压缩操作如下:
解压—>7zip极限压缩—>回复部分只能Store的资源