Android 应用瘦身
瘦身目的
开发过程中,随着功能不断的迭代,包体积也会逐渐变大,如果此时将包投入市场,将会引来客户的投诉和抱怨。体积大一方面是浪费用户数据流量,另一方面是增加了安装的等待时间,用户可能因为嫌弃安装包太大扬长而去,对企业利润有着直接的冲击,所以应用瘦身环节尤为重要。下面以企业项目做实例分享一下瘦身经验。
基本思路
其实很简单,主要分两大步骤:了解安装包的组成部分,对安装包的资源目录瘦身
1.安装包的组成部分
在代码结构双击打包好的apk会出现以下信息,可以直观的看到安装包结构:
通过上图,我们可以知道哪些模块最影响包的体积,根据对体积的影响程度做好排序,优化方向需围绕以下几个目录。
- assets
- lib
- res
- .dex
- .arsc
2.对安装包的资源目录瘦身
assets。该目录下存放资源文件,例如音频文件、json、web等。但下图可以看到该目录下存放的全是字体
针对字体,给出两种建议:a.先检查下所需字体Android是否提供
b.可以通过提取所需文字的ttf文件,大幅减小ttf体积,可以从几MB压缩到几KB不等
例如应用有语音播报功能,我们会将音频文件放置assets。这时优先考虑MP3、AAC等有损格式而非PCM、WAV无损格式。因为有损和无损语音质量差别甚微、但文件体积却天差地别
如非必要,考虑是否可通过网络存储、文件存储等其他方式保存资源,视具体情况而定,原则上尽量不参与打包
lib。lib下存放各种架构的so文件,现在大部分机器的cpu架构是armv7,所以我们打包时只需加入以下代码过滤掉其他的abi(最终根据实际情况)。具体路径:app目录下的build.gradle
附上代码:ndk {abiFilters "armeabi-v7a" }
效果:优化前
效果:优化后
res。这里都是一些资源文件,如下图所示,包含mipmap、drawble、layout等资源文件。优化方向主要有两个:
1.删除无用资源。有两种方式:这里可以用lint检测并物理删除目录下的无用资源,也可以在gradle设置shrinkResources为true,shrinkResources不会物理上删除无用资源,它是在打包时不将无用资源打进apk
使用第二种方式“shrinkResources“时需关注两点:
a.shrinkResources的使用一定要配合minifyEnabled,只有minifyEnabled为true时shrinkResources才会生效。具体原因就是我们的资源都是代码中使用的,我们需要知道哪些资源被代码使用,所以先得检测代码,即代码压缩/代码混淆b.shrinkResources默认发现代码中调用资源R.mipmap.a,则其他未使用资源R.mipmap.a*也会被打包进apk(*代表任意字符或字符串),所以如果您想自定义要保留的资源,则在路径res/raw/keep.xml定义规则
<?xml version="1.0" encoding="utf-8"?> <resources xmlns:tools="http://schemas.android.com/tools"tools:discard="@color/selector_tint_color"tools:keep="@layout/activity_test1,@layout/activity_test2"tools:shrinkMode="strict"/><!--discard:做严格检查--><!--keep :不做严格检查--><!--shrinkMode="strict" :该模式只保留在代码或者资源文件中明确引用的资源--><!--shrinkMode="safe" :该模式会保留所有明确引用的资源以及可能被 Resources.getIdentifier() 动态引用的资源-->
注意:当使用lint删除资源文件时,对于代码中使用了getIdentifier(String name, String defType, String defPackage)设置图片,这就需要格外小心了。我们一般的做法就是用lint检测无用资源然后删除,但getIdentifier()函数并不直接引用资源文件,而是输入资源名称,从而引起“资源文件不存在“的报错
2.图片优化。使用svg、webp、.9png格式的图片
下表是我测试的一组对照数据,根据自己的经验总结:
PNG 2.3M(大图) 124K(小图) SVG(矢量) 1.44M 257K 有细微失真 WebP 91.5K 16.3K 没有失真 a.背景图选用webp比较划算
b.小图标选用svg比较划算
c.对于图标相同只是颜色不同的无需再做图,我们只需要设置着色器android:tint属性就好了,可以省下好些图标空间
提一句:我们写layout布局时,1.可以将公共部分提取出来,2.改用约束布局尽量少一些layout层级。虽然对包体积不是很大,但多多少少会影响一些性能
.dex。该目录是.java文件在Davlik编译的字节码文件,相当于JVM的字节码.class,如下所示,是一些java文件。优化方向有以下几点:
1.将app目录下build.gradle文件中minifyEnabled设置为true,即代码压缩/代码混淆。这里需要注意的是对于从外部引入的一些三方库,不能够被混淆,需要在proguard-rules定义混淆规则2.移除废弃功能的代码。反正有Git,删了代码随时可以找回
3.提取重复代码
4.减少不必要的依赖。有时为了某个需求添加依赖,而后删除该需求后需记得删除该依赖
5.删除重叠框架。例如网络请求框架有okhttp、volley等,协同开发时往往会引入多种网络框架,这时只需保留一种框架
6.插件化。例如某些不常用的功能,既想拥有小体积,又想保留该功能,这时只需保留接口,通过网络从服务器下载相应功能的插件apk,在主应用中动态加载。关于插件化,我在后面的文章中会做简单介绍
.arsc。它是res的一套关系映射规则,通过以下这张图很清楚知道平时我们代码中使用的R.xxx.xxx其实就是通过这个关系映射找到的
像以上的string资源,默认它会编译出所有语言,如无必要,我们只需编译所需语言即可。此处以中文为例,只需在app目录下build.gradle中加入:resConfigs ‘zh’
代码如下:resConfigs "zh"
优化后效果:
总结
1.优化方向大致就是以上几点。通过一系列的优化,应用从39.2M优化到了15.6M。(截图并未截出assets、res、.dex优化后的apk大小,但上述观点阐明清晰,有疑问请留言)
2.关于优先级需要结合自身项目,根据优化难易程度、可优化幅度等多重因素综合定夺
拓展
1.assets、res之间的异同?
答:异:
- assets文件夹下的文件不会被映射到R.java中,res文件夹下的文件会被映射到R.java文件中(参考.arsc)
- assets访问需要AssetManager类,res访问直接使用资源ID
- assets可以自定义目录结构,res不可以自定义目录结构(除build.gradle声明外)
同:两者目录下的文件在打包后会原封不动的保存在apk包中,不会被编译成二进制
2.META-INF有什么用?
答:META-INF文件夹主要存放的配置信息,签名信息和版本信息,不能在瘦身时删除
上图中可发现CERT.SF,MANIFEST.MF,CERT.RSA和一些依赖包的version:
CERT.SF:
MANIFEST.MF:存放的是版本号,以及每个文件的哈希值,内容形式跟CERT.SF基本一致
CERT.RSA:签名相关
工具
字体提取工具:1.FontCreator、2.sfnttool
Android 应用瘦身相关推荐
- Android App 瘦身总结 第三章 代码混淆及优化
目录 一.代码混淆proguard 二.调整第三方库 三.环境差异依赖 四.代码习惯 五.插件化 六.总结 在前两章我们分别从图片资源和jni动态库这两个方面来分析apk瘦身的优化点 Android ...
- Android App 瘦身总结 第二章 jni动态库及cpu兼容
目录 一.利弊分析,按需引用 二.平台兼容 三.动态加载 四.总结 在前一章主要分析了图片资源部分的优化(Android App 瘦身总结 第一章 图片资源的优化处理_There is a Bug!! ...
- Android Apk瘦身指南大全
Android Apk瘦身指南大全 前言 为什么Android应用Apk要瘦身?虽然安装包大小对应用使用没有影响,但应用的安装包越大,用户下载的门槛越高,安装等待时间也会越长,特别是在移动网络情况下, ...
- Android APK 瘦身
Android APK 瘦身的几个方法 将项目中的图片由png.jpg转为webp格式.如下操作: 1.1选中图片或者含有图片的文件夹 右键选择Convert toWebP.. 1.2根据自身情况选择 ...
- Android App 瘦身总结 第一章 图片资源的优化处理
目录 一.去除无用的资源 二.忽略占比极少的分辨率 三.优化图片 四.使用更先进的图片格式 (1)使用矢量图 (2)使用webp图片格式 五.总结 当一款App经历了大量的迭代后,apk包会越来越臃肿 ...
- android APK瘦身全面总结——如何从32.6M到13.6M
前言 之前我简单介绍了关于svg图片瘦身的问题,在公司,瘦身这个问题是我提出来的,所以这锅我背了.公司项目是32.6M,我给自己的要求就是低于20M.上周花了一个星期瘦身,至于为什么花了一周,主要是s ...
- Android apk瘦身之使用TinyPng压缩图片
1 前言 Android apk太大了怎么办,有的时候需要减小apk的体积,例如上传到服务器的时候有文件大小的限制.百度一下,发现大致有以下几种方法: 使用混淆,减少代码体积 删除不使用的资源 减少使 ...
- Android apk瘦身讲解
apk瘦身 想办法较减少apk大小 必要性 同样功能,apk越小越好,用户下载动机更大 了解apk的组成 classes.dex:是java源码编译后生成的java字节码文件 resources.ar ...
- Android APK 瘦身 - JOOX Music项目实战
JOOX Music是腾讯海外布局的一个音乐产品,2014年发布以来已经成为5个国家和地区排名第一的音乐App.东南亚是JOOX Music的主要发行地区,由于JOOX Music所面对的市场存在很多 ...
- 深入探索 Android 包瘦身(上)
码个蛋(codeegg) 第 942 次推文 作者:jsonchao 链接:https://juejin.im/post/5e7ad1c0e51d450edc0cf053 今天分享一篇匠心制作的< ...
最新文章
- 怎么预约鸿蒙系统,华为鸿蒙2.0系统-鸿蒙2.0系统预约-艾艾软件园
- boost::geometry::closeable_view用法的测试程序
- NATAPP.CN 内网穿透教程
- 解决datagridview 横向的scrollbar不显示
- IE兼容/IE5兼容踩过的坑
- 熟练运用计算机的重要性,计算机专业实习目的和意义
- 解决Sublime提示 Sublime Text Error while loading PyV8 binary:exit code 1 Try to manually install Pyv8 fo
- jdk8,jdk10,jdk12新特性
- Java 多个文件压缩为一个zip文件
- C++制作“简单”小游戏
- 如何备份android10,安卓手机系统怎么备份
- 艾米丽Java游戏_艾米丽玩闹鬼 Emily Wants To Play中文游戏介绍_游戏库_巴士单机游戏...
- 2019/07/03 分布式系统概述(01)
- 让WP-Advanced-PDF插件支持中文
- 区块链和大数据结合方案
- 计算机辅助设计软件应用答案,专科《计算机辅助设计软件的应用》_试卷_答案.doc...
- nginx的作用与原理
- tuxera NTFS2022让磁盘读写管理格式化更轻松
- Exchange Server 2016 RTM快速部署指南
- 【生成模型】变分自编码器(VAE)及图变分自编码器(VGAE)
热门文章
- Chapter 5 (Limit Theorems): Markov and Chebyshev Inequalities (马尔可夫和切比雪夫不等式)
- 环比和同比的定义和应用
- ipv4v6双栈技术_什么是IPv6双栈技术
- windows 端口被System进程占用怎么解决?
- 【UTM使用_入侵防御策略】
- P80 例4-1 名和姓的对换问题。英国人和美国人姓名的书写形式是“名在前,姓在后”,但在有些情况下,需要把姓名写成“姓在前,名在后,中间加一个逗号”的形式。编写一个程序实现把“名在前,姓在后”的姓名
- 王者荣耀背景html,《王者荣耀》登录界面背景怎么修改 登录背景图片更换方法...
- double类型判断是否相等
- SpringBoot Validation参数校验 详解自定义注解规则和分组校验
- Redis Hget 命令