一、现在应用市场上十兆以上的APP比比皆是,究其原因主要有一下几种:
1、随着Android系统版本的碎片化发展以及手机类型的丰富,每个APP要支持的主流dpi分类越来越多,从最初的ldpi、mdpi、hdpi到现在的xhdpi、xxhdpi、xxxhdpi、tvdpi等
2、随着Android生态系统的不断发展成熟,出现了很多方便开发者的函数库和SDK,随着引入的函数库和SDK的增多,不可避免的引入了很多重复的功能代码及资源文件
3、用户对APP视觉要求的不断提高,APP提供的资源细节越来越丰富,占用的体积也不断上升
二、从APP文件的结构说起
应用市场上随便下载个APP文件,由于APP本身是一个压缩文件,因此我们可以将后缀名有.apk改成.zip,然后解压改文件,一般情况下,如果开发者在发布APK时没有对其进行加固等特色处理,我们应该能够得到如下图所示的而文件夹内容:
在进一步分析如何给APP瘦身之前,我们首先来了解一下APP文件所包含的东西,这样才能进行优化
1、AndroidMainiest.xml、lib、res及assets文件就不用说了,大家都知道是干什么的
2、META-INF:该目录存放的是签名相关的信息,用于验证APP包的完整性及保证系统的安全
3、classes.dex:应用程序可执行文件,对于一般的APP来说,方法数没有超过65k,那么打包后只有一个classes.dex文件,上图中有多个,说明方法数超过了65k
4、resources.arsc:资源索引表,用来描述具有ID值的资源的配置信息
从上面的文件目录分析来看,影响APP大小的有classes.dex、lib、asset、res及resources.arsc
三、优化图片
目前移动端Android平台原生的支持的图片格式主要有:jpeg、png、gif、bmp及WebP
jpeg:是一种广泛使用的有损压缩图像的标准格式
png:是一种无损压缩图片格式
gif:它的特点支持多帧动画
webp:2010发布的,它支持有损无损、支持完整的透明通道、也支持多帧动画,是一种比较理想的图片格式。在保证既保证图片质量又限制图片大小的需求下,webp是首选
1、使用无损压缩ImageOptim
它通过优化png压缩参数,移除冗余元数据以及非必需的颜色配置文件等方式,在不牺牲图片质量的前提下,即减少了png图片占用的空间,又提高了加载的速度
2、有损压缩ImageAlpha
相比较而言图片的大小得到极大的减低,当然同时图片的质量也会受到一定程度的影响,应该该工具压缩的图片,需要经过Ui设计的视觉确定
3、有损压缩TinyPNG
它以web站点的形式提供,没有独立的APP安装包,同所有的损压缩工具一样,经过压缩的图片,需要经过ui设计的视觉确认
4、png/jpeg转换为WebP
如果你的app最低支持到4.0,那么可以直接使用系统提供的能力来支持webp,如果是4.0以下的系统,也可以通过在app中集成第三方函数库,如webp-android-backport来实现
web的转换工具可以选择智图和iSparta
5、尽量使用NinePatch格式的图片,即.9图片
可以使用TinyPng工具来直观的观察压缩效果
6、使用Lint删除无用的资源
Android Lint天然集成在Android studio中,它会分析res目录下面的资源文件,但不会分析assets目录下面的资源文件
使用:在build中配置如下信息
lintOptions{ abortOnError true xmlReport false htmlReport true lintConfig file("${project.rootDir}/config/quality/lint/lint.xml") htmlOutput file("$project.buildDir/reports/lint/lint-result.html") xmlOutput file("$project.buildDir/reports/lint/lint-result.html") }
选中项目的app-->Analyze-->Inspect Code... 即可获取结果,而且类型为我们很好的进行分类,如下图
三、利用Android Gradle配置
1、minifyEnable
标志是否开启Proguard混淆,设置为true时需要同时设置Proguard配置文件名和规则,Proguard的作用不仅仅是混淆,它还具有压缩、优化等功能。它会遍历所有代码并找出没有引用到的代码,这些无用的代码在生成最终的APK文件之前会被剔除掉。同时Proguard会使用简短的字母组合替换原来的类名、属性名等,这些都能在一定程度上减少APP的大小
2、shrinkResources
标识是否去除无用的resource文件。需要注意的是,shrinkResources依赖的前提是minifyEnable设置为true时才会生效
buildTypes{ release{ minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro' } }
3、resConfigs
Android开发中不可避免的会引用第三放的函数库或者sdk,我们可能引入很多不需要使用到的资源文件,主要分为DPI目录(支持屏幕密度就有ldpi、mdpi、hdpi、xhpi、xxhdpi、xxxhdip,我们当然不可能为每一个屏幕密度土工一套资源文件,因此要剔除第三方的DIP目录及其文件),国际化文件(第三方一般为了使用会使用国际化文件,而我们的项目不需要,所以把不需要的国际化文件去除),配置如下
defaultConfig { //省略其他 resConfigs "en" , "fr" resConfigs "nodpi" , "hdpi" , "xhdpi" , "xxxhdpi" }
4、ndk.abiFilters
过滤掉不需要的ABI类型的.so文件
defaultConfig { applicationId "com.android.cleanprocesstool" ndk{ abiFilters "armeabi-v7a" , "x86" } }
5、重构代码和优化代码
6、资源混淆
资源文件的混淆方案目前有美团和微信两种,前者是通过修改AAPT在处理资源文件相关的源码达到资源文件名的替换;后者是通过直接修改resources.arsc文件达到资源文件名混淆。相比之下微信的方案更优,而且微信也将该方法开源出来了,地址https://github.com/shwenzhang/AndResGuard
7、插件化
不需要实现插件化框架,用来在线动态下载并加载各个插件