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

相关推荐
sun0077008 小时前
android ndk编译valgrind
android
AI视觉网奇9 小时前
android studio 断点无效
android·ide·android studio
jiaxi的天空9 小时前
android studio gradle 访问不了
android·ide·android studio
No Silver Bullet10 小时前
android组包时会把从maven私服获取的包下载到本地吗
android
catchadmin10 小时前
PHP serialize 序列化完全指南
android·开发语言·php
tangweiguo0305198711 小时前
Kable使用指南:Android BLE开发的现代化解决方案
android·kotlin
00后程序员张14 小时前
iOS App 混淆与资源保护:iOS配置文件加密、ipa文件安全、代码与多媒体资源防护全流程指南
android·安全·ios·小程序·uni-app·cocoa·iphone
柳岸风15 小时前
Android Studio Meerkat | 2024.3.1 Gradle Tasks不展示
android·ide·android studio
编程乐学15 小时前
安卓原创--基于 Android 开发的菜单管理系统
android
whatever who cares17 小时前
android中ViewModel 和 onSaveInstanceState 的最佳使用方法
android