Android应用包体积优化

为什么要优化安装包大小

提高应用的下载转化率和留存率。

1.用户可能会因为应用大小而放弃下载应用。

2.由于手机内存问题可能会导致用户卸载占用空间较大的应用。

除了下载下载转化率和留存率, 安装包体积优化还有一些理由:

  • 预装应用的推广成本.
  • 满足应用市场的最大包体积限制.
  • 在技术甚至业务层面, 我们可以重新审视我们的codebase, 是否需要删除一些低价值的业务, 清理无用的代码和资源, 进行进一步的重构和改善.

一、应用安装包构成分析

1.assets文件夹:存放一些配置文件、资源文件,assets不会自动生成对应的 ID,而是通过 AssetManager 类的接口获取。

2.META-INF文件夹:包含CERT.SF和CERT.RSA签名文件以及MANIFEST.MF 清单文件。保存应用的签名信息,签名信息可以验证 APK 文件的完整性。

3.res文件夹:没有被编译进resources.arsc文件的资源: layout, drawable等。这个目录存放资源文件,会自动生成对应的 ID 并映射到 .R 文件中,访问直接使用资源 ID。

4.resources.arsc:记录着资源文件和资源 ID 之间的映射关系,用来根据资源 ID 寻找资源。编译后的二进制资源文件, 包含了所有res/values中的XML内容, 如字符串, style等, 也包括对没编译进来的资源(比如layout和图片)的路径.

5.AndroidManifest.xml:这个文件用来描述 Android 应用的配置信息,一些组件的注册信息、可使用权限等。

6.classes.dex:Dalvik 字节码程序,让 Dalvik 虚拟机可执行,一般情况下,Android 应用在打包时通过 Android SDK 中的 dx 工具将 Java 字节码转换为 Dalvik 字节码。包含以Dalvik / ART虚拟机可理解的DEX文件格式编译的类。

7.lib:包含特定于处理器软件层的编译代码。该目录包含了每种平台的子目录,像armeabi,armeabi-v7a, arm64-v8a,x86,x86_64,和mips。

lib、class.dex和res占用了超过90%的空间,所以这三块是优化Apk大小的重点(实际情况不唯一)

二、常用方案

1.设备屏幕支持

当一个屏幕密度下没有提供特定的资源, Android会自动根据这个资源其他密度的版本进行缩放

我们通常会放置多套不同分辨率的图片以适配不同的屏幕,这里可以进行适当的删减。在实际使用中,只保留一到两套就足够了(保留一套的话建议保留xxhdpi,两套的话就加上hdpi).

2.压缩图文文件

可以用一些工具对PNG和JPEG图片进行无损压缩: 图片质量无损但是尺寸变小.

3.使用WebP格式的图片

可以使用WebP格式的图片, 比JPEG和PNG压缩得更好.

Android Studio提供了转换工具: Create WebP images

注意: Google Play只接受PNG作为launcher icon.

4.shape的使用

很多时候我们并不需要一个图片, 比如纯色或渐变色的背景, 带边框, 带圆角等.

<shape>尺寸就会比较小, 也不用多个密度的版本.

5.复用资源

这里的复用可以是改变了颜色和旋转方向等的复用.
比如改资源的tint, 或者把一个图旋转了之后再用. (thumb up变成thumb down了).

6.使用矢量图

可以使用矢量图来作为可伸缩的资源, 在Android中是VectorDrawable对象.

但是矢量图的渲染需要系统的时间花销, 所以推荐只有小的icon使用矢量图.

7.逐帧动画

不要再使用很多个图片逐帧播放来实现一个动画效果了.
尽量用改变属性的动画来节省资源使用.

另外还有一些手段比如在程序中绘制, 而不是使用图片.

8.Lint静态分析

针对不用的资源, 可以专门这样检查:
在Android Studio中: Analyze -> Run Inspection by Name... -> Unused Resources

扫描后会对所有未使用的资源给出警告.

注意, 因为是Lint静态检查, 所以会有一些错报和漏报的情况:

  • assets/目录不被扫描.
  • 检测不到第三方库中带来的不用的资源.
  • 错报: 资源在项目中实际上用了, 但是被检测出来了. 如果资源是被动态引用的, 比如用getIdntifer()方法, 拼名字使用, 会被lint错误地报告说没有用到.
  • 漏报: 实际上没有用到, 但是没有检测出来. 这是因为还有另一个没有用到的代码引用了这个资源.
    比如有一个没有人用的Fragment, 它的布局文件就不会被检测出来, 因为写在了代码里. (注意: 如果是不用的布局中include了另一个布局, 这两个布局都能被检测出来.)

静态检查只是帮我们检测并报告, 真正要移除这些资源还得靠我们手动删除.

lintOptions { 
    abortOnError false 
}

9.代码压缩和混淆

ProGuard -> R8会帮我们删除不用的代码, 进行名称改写和代码优化.

minifyEnabled true

不用的代码被移除了, 类和成员的名称都被改得很短, 从而有效地减小了dex文件的大小.
这里需要注意rules的编写, 不要过度保护.

比较追求极致的方法会从这个方面下手, 进一步细化优化ProGuard Rules, 以达到更深度的混淆和压缩.

10.减少lib文件大小,精简支持的cpu架构:

由于引用了很多第三方库,lib文件夹占用的空间通常都很大,特别是有so库的情况下。很多so库会同时引入armeabi、armeabi-v7a和x86这几种类型,这里可以只保留armeabi或armeabi-v7a的其中一个就可以了,实际上微信等主流app都是这么做的。

只需在build.gradle直接配置即可,NDK配置同理

defaultConfig {
    ndk {
        abiFilters 'armeabi-v7a'
    }
}

11.精简支持语言

resConfigs "en", "zh-rCN"

 

https://www.jianshu.com/p/a0db5e588506

https://www.cnblogs.com/cr330326/p/8011523.html

https://www.cnblogs.com/mengdd/p/reduce-size-of-android-app.html

https://www.jianshu.com/p/c76a032b0f4c

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值