瘦身目的

开发过程中,随着功能不断的迭代,包体积也会逐渐变大,如果此时将包投入市场,将会引来客户的投诉和抱怨。体积大一方面是浪费用户数据流量,另一方面是增加了安装的等待时间,用户可能因为嫌弃安装包太大扬长而去,对企业利润有着直接的冲击,所以应用瘦身环节尤为重要。下面以企业项目做实例分享一下瘦身经验。

基本思路

其实很简单,主要分两大步骤:了解安装包的组成部分,对安装包的资源目录瘦身

1.安装包的组成部分

在代码结构双击打包好的apk会出现以下信息,可以直观的看到安装包结构:

通过上图,我们可以知道哪些模块最影响包的体积,根据对体积的影响程度做好排序,优化方向需围绕以下几个目录。

  1. assets
  2. lib
  3. res
  4. .dex
  5. .arsc

2.对安装包的资源目录瘦身

  1. assets。该目录下存放资源文件,例如音频文件、json、web等。但下图可以看到该目录下存放的全是字体

    针对字体,给出两种建议:

    a.先检查下所需字体Android是否提供

    b.可以通过提取所需文字的ttf文件,大幅减小ttf体积,可以从几MB压缩到几KB不等

    例如应用有语音播报功能,我们会将音频文件放置assets。这时优先考虑MP3、AAC等有损格式而非PCM、WAV无损格式。因为有损和无损语音质量差别甚微、但文件体积却天差地别

    如非必要,考虑是否可通过网络存储、文件存储等其他方式保存资源,视具体情况而定,原则上尽量不参与打包

  2. lib。lib下存放各种架构的so文件,现在大部分机器的cpu架构是armv7,所以我们打包时只需加入以下代码过滤掉其他的abi(最终根据实际情况)。具体路径:app目录下的build.gradle

    附上代码:

    ndk {abiFilters  "armeabi-v7a"
    }
    

    效果:优化前
    效果:优化后

  3. 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层级。虽然对包体积不是很大,但多多少少会影响一些性能

  4. .dex。该目录是.java文件在Davlik编译的字节码文件,相当于JVM的字节码.class,如下所示,是一些java文件。优化方向有以下几点:

    1.将app目录下build.gradle文件中minifyEnabled设置为true,即代码压缩/代码混淆。这里需要注意的是对于从外部引入的一些三方库,不能够被混淆,需要在proguard-rules定义混淆规则

    2.移除废弃功能的代码。反正有Git,删了代码随时可以找回

    3.提取重复代码

    4.减少不必要的依赖。有时为了某个需求添加依赖,而后删除该需求后需记得删除该依赖

    5.删除重叠框架。例如网络请求框架有okhttp、volley等,协同开发时往往会引入多种网络框架,这时只需保留一种框架

    6.插件化。例如某些不常用的功能,既想拥有小体积,又想保留该功能,这时只需保留接口,通过网络从服务器下载相应功能的插件apk,在主应用中动态加载。关于插件化,我在后面的文章中会做简单介绍

  5. .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之间的异同?

答:异:

  1. assets文件夹下的文件不会被映射到R.java中,res文件夹下的文件会被映射到R.java文件中(参考.arsc)
  2. assets访问需要AssetManager类,res访问直接使用资源ID
  3. 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 应用瘦身相关推荐

  1. Android App 瘦身总结 第三章 代码混淆及优化

    目录 一.代码混淆proguard 二.调整第三方库 三.环境差异依赖 四.代码习惯 五.插件化 六.总结 在前两章我们分别从图片资源和jni动态库这两个方面来分析apk瘦身的优化点 Android ...

  2. Android App 瘦身总结 第二章 jni动态库及cpu兼容

    目录 一.利弊分析,按需引用 二.平台兼容 三.动态加载 四.总结 在前一章主要分析了图片资源部分的优化(Android App 瘦身总结 第一章 图片资源的优化处理_There is a Bug!! ...

  3. Android Apk瘦身指南大全

    Android Apk瘦身指南大全 前言 为什么Android应用Apk要瘦身?虽然安装包大小对应用使用没有影响,但应用的安装包越大,用户下载的门槛越高,安装等待时间也会越长,特别是在移动网络情况下, ...

  4. Android APK 瘦身

    Android APK 瘦身的几个方法 将项目中的图片由png.jpg转为webp格式.如下操作: 1.1选中图片或者含有图片的文件夹 右键选择Convert toWebP.. 1.2根据自身情况选择 ...

  5. Android App 瘦身总结 第一章 图片资源的优化处理

    目录 一.去除无用的资源 二.忽略占比极少的分辨率 三.优化图片 四.使用更先进的图片格式 (1)使用矢量图 (2)使用webp图片格式 五.总结 当一款App经历了大量的迭代后,apk包会越来越臃肿 ...

  6. android APK瘦身全面总结——如何从32.6M到13.6M

    前言 之前我简单介绍了关于svg图片瘦身的问题,在公司,瘦身这个问题是我提出来的,所以这锅我背了.公司项目是32.6M,我给自己的要求就是低于20M.上周花了一个星期瘦身,至于为什么花了一周,主要是s ...

  7. Android apk瘦身之使用TinyPng压缩图片

    1 前言 Android apk太大了怎么办,有的时候需要减小apk的体积,例如上传到服务器的时候有文件大小的限制.百度一下,发现大致有以下几种方法: 使用混淆,减少代码体积 删除不使用的资源 减少使 ...

  8. Android apk瘦身讲解

    apk瘦身 想办法较减少apk大小 必要性 同样功能,apk越小越好,用户下载动机更大 了解apk的组成 classes.dex:是java源码编译后生成的java字节码文件 resources.ar ...

  9. Android APK 瘦身 - JOOX Music项目实战

    JOOX Music是腾讯海外布局的一个音乐产品,2014年发布以来已经成为5个国家和地区排名第一的音乐App.东南亚是JOOX Music的主要发行地区,由于JOOX Music所面对的市场存在很多 ...

  10. 深入探索 Android 包瘦身(上)

    码个蛋(codeegg) 第 942 次推文 作者:jsonchao 链接:https://juejin.im/post/5e7ad1c0e51d450edc0cf053 今天分享一篇匠心制作的< ...

最新文章

  1. 怎么预约鸿蒙系统,华为鸿蒙2.0系统-鸿蒙2.0系统预约-艾艾软件园
  2. boost::geometry::closeable_view用法的测试程序
  3. NATAPP.CN 内网穿透教程
  4. 解决datagridview 横向的scrollbar不显示
  5. IE兼容/IE5兼容踩过的坑
  6. 熟练运用计算机的重要性,计算机专业实习目的和意义
  7. 解决Sublime提示 Sublime Text Error while loading PyV8 binary:exit code 1 Try to manually install Pyv8 fo
  8. jdk8,jdk10,jdk12新特性
  9. Java 多个文件压缩为一个zip文件
  10. C++制作“简单”小游戏
  11. 如何备份android10,安卓手机系统怎么备份
  12. 艾米丽Java游戏_艾米丽玩闹鬼 Emily Wants To Play中文游戏介绍_游戏库_巴士单机游戏...
  13. 2019/07/03 分布式系统概述(01)
  14. 让WP-Advanced-PDF插件支持中文
  15. 区块链和大数据结合方案
  16. 计算机辅助设计软件应用答案,专科《计算机辅助设计软件的应用》_试卷_答案.doc...
  17. nginx的作用与原理
  18. tuxera NTFS2022让磁盘读写管理格式化更轻松
  19. Exchange Server 2016 RTM快速部署指南
  20. 【生成模型】变分自编码器(VAE)及图变分自编码器(VGAE)

热门文章

  1. Chapter 5 (Limit Theorems): Markov and Chebyshev Inequalities (马尔可夫和切比雪夫不等式)
  2. 环比和同比的定义和应用
  3. ipv4v6双栈技术_什么是IPv6双栈技术
  4. windows 端口被System进程占用怎么解决?
  5. 【UTM使用_入侵防御策略】
  6. P80 例4-1 名和姓的对换问题。英国人和美国人姓名的书写形式是“名在前,姓在后”,但在有些情况下,需要把姓名写成“姓在前,名在后,中间加一个逗号”的形式。编写一个程序实现把“名在前,姓在后”的姓名
  7. 王者荣耀背景html,《王者荣耀》登录界面背景怎么修改 登录背景图片更换方法...
  8. double类型判断是否相等
  9. SpringBoot Validation参数校验 详解自定义注解规则和分组校验
  10. Redis Hget 命令