Android APK优化系列瘦身篇:实战一个APK从11MB压缩到4MB,APK无用资源去除与代码压缩、混淆,瘦身维度的选型分析

目录:

  1. 为什么要进行APK瘦身呢?
  2. APK瘦身主要是瘦身哪些呢?
    a. 优化resources.arsc:
    b. res优化
    c. lib优化
    d. 资源优化,代码混淆和压缩
  3. 总结

一、为什么要进行APK瘦身呢?


  1. 减少下载时间和流量消耗:APK文件越小,用户在下载过程中消耗的流量就越少,下载时间也越短,这直接提升了用户的下载体验。
  2. 加快安装速度:较小的APK文件在安装过程中需要处理的数据量更少,因此安装速度更快,减少了用户的等待时间。
  3. 提高加载速度:APK瘦身通常包括优化资源文件和代码,减少不必要的加载项,从而加快应用的启动速度和页面加载速度。

下面我们从通过实战案例,将一个APK从11MB压缩到4MB。

二、APK瘦身主要是瘦身哪些呢?


首先我们先看看APK的内容有哪些呢, 将apk直接拖入到android studio中,可以分析出lib,res等文件的大小,如下图:我们主要是优化着一些比较大的内容:
● META-INF:包含APK的签名信息(如MANIFEST.MF文件),这是用于验证APK文件完整性和真实性的关键信息。

● AndroidManifest.xml:这是APK的清单文件,它描述了应用的权限、组件(如活动、服务等)、版本信息等重要元数据。这个文件对于Android系统来说是理解和运行APK的基础。

● classes.dex:是java源码编译后生成的java字节码文件,因方法数限制拆分了多个dex,是APK中最重要的代码部分。随着应用的不断发展,这部分的代码量可能会显著增加。

● resources.arsc:resources.arsc 是 Android APK 打包过程中生成的一个重要文件,它是资源索引文件,负责将代码中的资源引用映射到 res/ 目录下的具体资源文件或内容。

● res/:资源文件夹,包含了应用程序使用的各种资源文件,如图片(drawable/)、布局(layout/)、字符串(values/)等。这些资源文件往往占据了APK文件的较大空间,特别是高分辨率的图片资源。

● assets/:资产文件夹,包含了应用程序使用的原始文件,如音频、视频等。这部分的内容也可能对APK的大小产生显著影响。

● lib/:库文件夹,包含了应用程序使用的外部库文件(.so文件),主要是本地代码库。这些库文件可能针对不同的CPU架构进行了优化,从而增加了APK的复杂性和大小。


2.1 resources.arsc优化

简介:resources.arsc 是 Android APK 打包过程中生成的一个重要文件,它是资源索引文件,负责将代码中的资源引用映射到 res/ 目录下的具体资源文件或内容。


优化点:string

可以看到,有很多种语言的翻译,这些翻译,都是android自动给我们生成的,不是我们自己创建的。

一般情况下,这些翻译不一定是适用于我们,也可能存在错误,不符合当地语言,所以我们可以选择去掉不用。我们只需要添加如下这个操作,就可以去掉,或者保留其中一些:

然后重新生成APK,我们可以看到大小明显变小了,从之前的556KB变成了380KB, 减少不必要的语言

2.2 res优化:


图片优化

一般我们常用的就是,jpg或png。对图片进行优化,一般是转换成svg,或者webp。但是呢,也不能盲目的转。首先我们先了解一下他们的应用场景。


svg

简介:

SVG是很多种矢量图中的一种,它的特点是使用XML来描述图片,也就是它的文件内容,就是一个xml,可以使用文本编辑器进行编辑和修改。

比位图格式,SVG文件通常更小,特别是当图形较简单时。

svg 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<svg width="80px" height="80px" viewBox="0 0 80 80" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
    <title>pic_shurucuowu</title>
    <defs>
        <polygon id="path-1" points="0.00585365854 0.0780487805 79.9218537 0.0780487805 79.9218537 79.9999024 0.00585365854 79.9999024"></polygon>
    </defs>
    <g id="后台页面" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
        <g id="Artboard" transform="translate(-2107.000000, -252.000000)">
            <g id="pic_shurucuowu" transform="translate(2107.000000, 252.000000)">
                <mask id="mask-2" fill="white">
                    <use xlink:href="#path-1"></use>
                </mask>
                <g id="Clip-2"></g>
                <path d="M39.9611707,79.9999024 C62.0308293,79.9999024 79.9218537,62.108878 79.9218537,40.0392195 C79.9218537,17.9690732 62.0308293,0.0780487805 39.9611707,0.0780487805 C17.8910244,0.0780487805 0,17.9690732 0,40.0392195 C0,62.108878 17.8910244,79.9999024 39.9611707,79.9999024 Z M44.9562012,62.514439 C44.9576585,63.1778537 44.6947317,63.8147317 44.225561,64.2838049 C43.7560976,64.7533659 43.1193171,65.0162927 42.4558049,65.0148353 L37.4607805,65.0148353 C36.7980488,65.0148353 36.1623415,64.7510244 35.6943415,64.2819512 C35.2263415,63.8127805 34.9641951,63.1767805 34.9656524,62.514439 L34.9656524,57.5246829 C34.9656524,56.1432195 36.0845854,55.0242927 37.4660488,55.0242927 L42.4614634,55.0242927 C43.8372683,55.0242927 44.9562012,56.1432195 44.9562012,57.5246829 L44.9562012,62.514439 Z M44.9562012,42.5338537 C44.9576585,43.1973659 44.6947317,43.8341463 44.225561,44.3036098 C43.7560976,44.7727805 43.1193171,45.0357073 42.4558049,45.03425 L37.4607805,45.03425 C36.7980488,45.03425 36.1623415,44.7705366 35.6943415,44.3013659 C35.2263415,43.8321951 34.9641951,43.1961951 34.9656524,42.5338537 L34.9656524,17.5639024 C34.9656524,16.1881951 36.0845854,15.0692683 37.4660488,15.0692683 L42.4614634,15.0692683 C43.8372683,15.0692683 44.9562012,16.1881951 44.9562012,17.5696585 L44.9562012,42.5395122 L44.9562012,42.5338537 Z" id="Fill-1" fill="#FF817C" mask="url(#mask-2)"></path>
            </g>
        </g>
    </g>
</svg>

因为它是一个文件,所以每次都需要解析文件后才能进行渲染,它的好处就是,不管放大多少,都不会出现锯齿的这种情况。但也因此多了一个解析的步骤。

应用场景:

它的应用场景是 图标和图形设计:如应用图标、按钮图标等,这些图形通常简单且需要保持在不同尺寸下的清晰度。颜色最好是纯色的。过于丰富色彩的图片,可能无法显示,并且解析会比较复杂。

SVG加载速度会快于PNG,但渲染速度会慢于PNG,毕竟PNG有硬件加速,但平均下来,加载速度的提升弥补了绘制的速度缺陷

类似如下这种就可以使用:

缺点

渲染性能:在Android设备上,大量使用SVG可能会导致渲染性能下降,因为每个SVG都需要被解析和渲染。

不支持复杂的图像效果:如阴影、模糊等,这些效果需要额外的代码或工具来实现。


webp

简介

Webp是由Google开发的一种旨在提供更高效图像压缩的图像格式。相比JPG和PNG,WebP在保持相同图像质量的同时,可以提供更小的文件大小。 渲染速度快。

应用场景

网络传输:由于高压缩率,WebP非常适合用于网络传输,可以减少数据使用量和加载时间。

高质量图像:对于需要高质量图像但又不希望文件过大的场景,WebP是一个很好的选择。

我们可以看到,百度等的图片,保存下来,都是webp格式的。


JPG

简介:

广泛应用于照片和复杂图像的存储。 渲染速度快。

应用场景

高保真图片(照片),非常适合用于存储照片和复杂图像,如风景照、人物照等。 一般不用于logo,文件会失真,出现齿轮。jpg格式中不能有透明区域,在保存时会自动保存为白色


PNG

简介

支持透明背景和多种颜色。 渲染速度快。

应用场景

● 图标和图形设计:如应用图标、按钮图标等,这些图形通常不需要很高的压缩率且需要保持透明背景。

● 高质量图像:对于需要高质量图像且不希望损失任何图像信息的场景,PNG是一个很好的选择。

● 支持透明度。


总结

  1. SVG一般是用于纯色的图标;svg至少比jpg小一半,图片越大,体积越明显。
  2. Webp一般用与网络传输的图片;
  3. PNG格式也常用于屏幕截图和界面设计稿的保存。由于它支持透明背景和多种颜色深度,可以确保设计稿在不同设备和环境下的显示效果一致。
  4. 由于JPG格式的广泛支持和较高的压缩率,它成为网络上共享图片的首选格式之一。Android应用中的图片分享功能通常会使用JPG格式来发送图片。
    所以我们可以将图片转换成对应的格式,会减少体积。

注意点:

  1. 在Android 5.0之前的版本中,Android系统原生并不支持SVG格式。这意味着在这些版本的Android设备上,直接使用SVG文件可能会遇到问题,如无法加载或显示。
  2. 可以使用第三方库:开发者可以通过引入第三方库(如Android SVG库)来在旧版本的Android系统上实现SVG图片的加载和显示。这些库提供了必要的解析和渲染功能,使得SVG文件能够在不支持原生SVG的Android版本上得到应用。
  3. 图片的优化的优先级,还是比较低!因为优化成本还是比较高的。要结合实际情况来。

2.3 lib优化


so库瘦身

所有的架构设备x86、x8-64、armeabi-v7a、arm64-v8a都支持armeabi架构的.so文件,所以我们可以根据自己的业务需求选择使用armeabi、armeabi-v7a或者arm64-v8a进行支持 。

  1. x86:基于Intel和AMD等公司的x86架构的CPU,主要用于PC和某些平板电脑。在Android设备上,x86架构的手机相对较少,但一些设备(如部分Intel Atom处理器的平板)会使用这种架构。
  2. x86-64(也称为x64):x86架构的64位版本,支持更大的内存寻址空间和更高效的计算。在Android设备上,x86-64架构的设备也逐渐增多,但总体上仍不如ARM架构普及。
  3. armeabi:基于ARMv5架构的ABI,是Android早期支持的一种架构。它不支持硬件浮点运算,因此在需要大量计算的应用中性能较差。随着硬件的发展,armeabi架构的设备已经越来越少。
  4. armeabi-v7a:基于ARMv7架构的ABI,支持硬件浮点运算和高级SIMD(单指令多数据)指令集,是目前Android设备中最主流的架构之一。armeabi-v7a设备可以兼容armeabi的.so文件,但性能会有所下降。
  5. arm64-v8a:基于ARMv8架构的64位ABI,支持更高效的计算和更大的内存寻址空间。随着Android设备硬件的升级,越来越多的设备开始支持arm64-v8a架构。arm64-v8a设备可以兼容armeabi-v7a和armeabi的.so文件,但同样可能存在性能下降的情况。

按照如下设置,保留我们需要的。

如上图所以优化完成之后apk的lib包中就只有'arm64-v8a','armeabi-v7a'两种架构了 ,我们在开发Android应用时需要根据实际情况选择合适的ABI来编译和打包.so文件。

2.4 代码混淆、代码压缩:


shrinkResources = true 和 minifyEnabled = true 是Android开发中用于优化APK大小的两种配置选项,它们通常用于Gradle构建脚本中的android块的buildTypes部分,特别是针对release构建类型。这些设置帮助开发者减少最终APK的大小,加快应用的加载时间,并可能提高应用的性能。

如果 要 使用 删除无用资源shrinkResources = true, 必须要 打开混淆minifyEnabled = true
优化前:大小11.7MB

优化后:4.7MB


shrinkResources = true

作用:shrinkResources是Android Gradle插件提供的一个功能,用于移除未使用的资源文件。这意味着,如果你的应用代码中没有引用某个资源(如图片、布局文件、动画等),那么这些资源就不会被包含在最终的APK中。这有助于显著减少APK的大小。是资源压缩,而不是说图片不打包进来哈。内部资源数据全部剔除

使用场景:当你想要发布一个更小的APK,以便用户更快地下载和安装,或者当你的应用包含了很多资源,但实际上很多资源在应用中并没有用到时。


minifyEnabled = true

作用:minifyEnabled启用了ProGuard的代码压缩和混淆功能。ProGuard是一个Java类文件优化器、压缩器和混淆器。它通过删除未使用的代码和类,优化字节码,以及用短名称替换类、方法和字段名来减少APK的大小。同时,混淆还可以增加逆向工程的难度,提高应用的安全性。

使用场景:当你想要发布一个更小的APK,或者当你需要增加应用的安全性,防止他人轻易地反编译和查看你的源代码时。


注意事项

● 在启用这些优化之前,请确保你的应用已经过充分的测试,以避免优化过程中可能引入的问题,如由于移除了必要的代码或资源而导致的崩溃或功能缺失。

● 对于minifyEnabled,你可能需要配置ProGuard规则文件(通常是proguard-rules.pro),以确保重要的代码、类和资源不被误删除或混淆。

● 考虑到兼容性和安全性,通常建议在发布版本(release)中启用这些优化,而在开发版本(debug)中保持禁用状态,以便更容易地调试和测试应用。

四、总结


apk瘦身是需要持续进行的,在后期开发新功能的时候,发版之前需与上一个版本包体积对比,超过阈值则必须要优化 。

相关推荐
找藉口是失败者的习惯1 小时前
Jetpack Compose 如何布局解析
android·xml·ui
Estar.Lee6 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
温辉_xh6 小时前
uiautomator案例
android
工业甲酰苯胺7 小时前
MySQL 主从复制之多线程复制
android·mysql·adb
少说多做3438 小时前
Android 不同情况下使用 runOnUiThread
android·java
Estar.Lee9 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
找藉口是失败者的习惯10 小时前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey11 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!12 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟13 小时前
Android音频采集
android·音视频