缩减应用大小  

您所在的位置:网站首页 安卓优化代码 缩减应用大小  

缩减应用大小  

2023-10-10 09:08| 来源: 网络整理| 查看: 265

通常情况下,用户不会下载那些看起来太大的应用,尤其是在仍然使用稳定性欠佳的 2G 和 3G 网络或按流量计费的新兴市场。本页面介绍了如何缩减应用的下载大小,从而吸引更多用户下载。

使用 Android App Bundle 上传应用

如需在发布到 Google Play 时立即缩减应用大小,最简单的方法就是将应用上传为 Android APP Bundle,这是一种全新的上传格式,其中包含应用的所有编译好的代码和资源,但 APK 生成及签名工作则交给 Google Play 来处理。

Google Play 的新应用服务模式随后会使用您的 app bundle 针对每位用户的设备配置生成并提供经过优化的 APK,因此用户只需下载运行您的应用所需的代码和资源。您不必再通过构建、签署和管理多个 APK 来支持不同的设备,而用户也可以获得经过优化后变得更小的下载文件包。

请注意,由于 Google Play 对使用 App Bundle 发布的应用强制施加了不超过 150MB 的压缩下载大小限制,因此我们仍然建议您遵守本页面介绍的指南,尽可能缩减应用的下载大小。

对于您通过上传签名的 APK 发布到 Google Play 的应用,其压缩下载大小限制为不超过 100MB

了解 APK 结构

在讨论如何缩减应用的大小之前,有必要了解下应用 APK 的结构。APK 文件由一个 Zip 压缩文件组成,其中包含构成应用的所有文件。这些文件包括 Java 类文件、资源文件和包含已编译资源的文件。

APK 包含以下目录:

META-INF/:包含 CERT.SF 和 CERT.RSA 签名文件,以及 MANIFEST.MF 清单文件。 assets/:包含应用的资源;应用可以使用 AssetManager 对象检索这些资源。 res/:包含未编译到 resources.arsc 中的资源。 lib/:包含特定于处理器软件层的已编译代码。此目录包含每种平台类型的子目录,如 armeabi、armeabi-v7a、arm64-v8a、x86、x86_64 和 mips。

APK 还包含以下文件。在这些文件中,只有 AndroidManifest.xml 是必需的。

resources.arsc:包含已编译的资源。此文件包含 res/values/ 文件夹的所有配置中的 XML 内容。打包工具会提取此 XML 内容,将其编译为二进制文件形式,并压缩内容。此内容包括语言字符串和样式,以及未直接包含在 resources.arsc 文件中的内容(例如布局文件和图片)的路径。 注意:请勿在 APK 中压缩此文件。 classes.dex:包含以 Dalvik/ART 虚拟机可理解的 DEX 文件格式编译的类。 AndroidManifest.xml:包含核心 Android 清单文件。 此文件列出了应用的名称、版本、访问权限和引用的库文件。此文件使用 Android 的二进制 XML 格式。 缩减资源数量和大小

APK 的大小会影响应用加载速度、使用的内存量以及消耗的电量。缩减 APK 大小的一种简单方法是缩减其包含的资源数量和大小。具体来说,您可以移除应用不再使用的资源,并且可以用可伸缩的 Drawable 对象取代图片文件。此部分将讨论上述这些方法,以及另外几种可减少应用中的资源以缩减 APK 总大小的方法。

移除未使用的资源

lint 工具是 Android Studio 中附带的静态代码分析器,可检测到 res/ 文件夹中未被代码引用的资源。当 lint 工具发现项目中有可能未使用的资源时,会显示一条消息,如下例所示。

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]

注意:lint 工具不会扫描 assets/ 文件夹、通过反射引用的资源或已链接至应用的库文件。此外,它也不会移除资源,而只会提醒您它们的存在。

您添加到代码的库可能包含未使用的资源。如果您在应用的 build.gradle 文件中启用了 shrinkResources,则 Gradle 可以代表您自动移除资源。

Groovy android { // Other settings buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } Kotlin android { // Other settings buildTypes { getByName("release") { minifyEnabled = true shrinkResources = true proguardFiles(getDefaultProguardFile('proguard-android.txt'), "proguard-rules.pro") } } }

如需使用 shrinkResources,您还必须启用代码缩减功能。在构建流程中,R8 首先会移除未使用的代码。然后,Android Gradle 插件会移除未使用的资源。

如需详细了解代码和资源缩减以及 Android Studio 帮助您缩减 APK 大小的其他方式,请参阅压缩、混淆和优化应用。

在 Android Gradle Plugin 0.7 及更高版本中,您可以声明应用支持的配置。Gradle 会使用 resConfig 和 resConfigs 变体以及 defaultConfig 选项将这些信息传递给构建系统。随后,构建系统会阻止来自其他不受支持配置的资源出现在 APK 中,从而缩减 APK 的大小。有关此功能的详情,请参见移除未使用的备用资源。

尽量减少库中的资源使用量

在开发 Android 应用时,您通常需要使用外部库来提高应用的可用性和多功能性。例如,您可以引用 Android 支持库来提升旧设备上的用户体验,也可以使用 Google Play 服务获取应用中文本的自动翻译。

如果库是为服务器或桌面设备设计的,则它可能包含应用不需要的许多对象和方法。如需仅包含您的应用所需的库部分,您可以编辑库的文件(如果库许可允许您修改库)。您还可以使用其他适合移动设备的库为应用添加特定功能。

注意:代码缩减可以清理库的一些不必要代码,但可能无法移除大型内部依赖项。

原生动画图片解码

在 Android 12(API 级别 31)中,NDK ImageDecoder API 已扩展为对使用动画 GIF 和动画 WebP 文件格式的图片的所有帧和时间数据进行解码。在 Android 11 中引入该 API 时,该 API 仅从这些格式的动画中解码第一张图片。

使用 ImageDecoder(而非第三方库)可进一步缩减 APK 大小,并从未来与安全性和性能相关的更新中受益。

如需详细了解该 API,请参阅 API reference 和 GitHub 上的示例。

仅支持特定密度

Android 支持多种设备,涵盖了各种屏幕密度。在 Android 4.4(API 级别 19)及更高版本中,框架支持各种密度:ldpi、mdpi、tvdpi、hdpi, xhdpi、xxhdpi 和 xxxhdpi。尽管 Android 支持所有这些密度,但您无需将光栅化资源导出为每个密度。

如果您知道只有一小部分用户拥有具有特定密度的设备,请考虑是否需要将这些密度捆绑到您的应用中。如果您不添加用于特定屏幕密度的资源,Android 会自动缩放最初为其他屏幕密度设计的现有资源。

如果您的应用仅需要缩放的图片,则可以通过在 drawable-nodpi/ 中使用图片的单个变体来节省更多空间。我们建议每个应用至少包含一个 xxhdpi 图片变体。

有关屏幕密度的详情,请参见屏幕尺寸和密度。

使用可绘制对象

某些图片不需要静态图片资源;框架可以在运行时动态绘制图片。Drawable 对象(XML 中为 )会占用 APK 中的少量空间。此外,XML Drawable 对象会生成符合 Material Design 准则的单色图片。

重复使用资源

您可以为图片的变体添加单独的资源,例如同一图片经过色调调整、阴影设置或旋转的版本。不过,我们建议您重复使用同一组资源,并在运行时根据需要对其进行自定义。

Android 提供了一些实用程序来更改资源的颜色。在 Android 5.0(API 级别 21)及更高版本上,使用 android:tint 和 tintMode 属性,对于较低版本的平台,则使用 ColorFilter 类。

您还可以省略仅是另一个资源的旋转等效项的资源。以下代码段提供了一个示例,展示了通过绕图片中心位置旋转 180 度,将“拇指向上”变为“拇指向下”:

从代码进行渲染

您还可以通过按一定程序渲染图片来缩减 APK 大小。 按一定程序渲染可以释放空间,因为您不再在 APK 中存储图片文件。

压缩 PNG 文件

aapt 工具可以在构建流程中通过无损压缩来优化放置在 res/drawable/ 中的图片资源。例如,aapt 工具可以通过调色板将不需要超过 256 种颜色的真彩色 PNG 转换为 8 位 PNG。这样做会生成质量相同但内存占用量更小的图片。

请记住,aapt 具有以下限制:

aapt 工具不会缩减 asset/ 文件夹中包含的 PNG 文件。 图片文件需要使用 256 种或更少的颜色才可供 aapt 工具进行优化。 aapt 工具可能会膨胀已压缩的 PNG 文件。为避免出现这种情况,您可以使用 isCrunchPngs 标志为 PNG 文件停用此过程: Groovy buildTypes.all { isCrunchPngs = false } Kotlin buildTypes.all { isCrunchPngs = false } 压缩 PNG 和 JPEG 文件

您可以使用 pngcrush、pngquant 或 zopflipng 等工具缩减 PNG 文件的大小,同时不损失画质。所有这些工具都可以缩减 PNG 文件的大小,同时保持肉眼感知的画质不变。

pngcrush 工具尤为有效:该工具会迭代 PNG 过滤器和 zlib (Deflate) 参数,使用过滤器和参数的每个组合来压缩图片。然后,它会选择可产生最小压缩输出的配置。

如需压缩 JPEG 文件,您可以使用 packJPG 和 guetzli 等工具。

使用 WebP 文件格式

如果以 Android 3.2(API 级别 13)及更高版本为目标,您还可以使用 WebP 文件格式的图片(而不是使用 PNG 或 JPEG 文件)。WebP 格式提供有损压缩(如 JPEG)以及透明度(如 PNG),不过与 JPEG 或 PNG 相比,这种格式可以提供更好的压缩效果。

您可以使用 Android Studio 将现有 BMP、JPG、PNG 或静态 GIF 图片转换为 WebP 格式。如需了解详情,请参阅使用 Android Studio 创建 WebP 图片。

使用矢量图形

您可以使用矢量图形创建与分辨率无关的图标和其他可伸缩媒体。使用这些图形可以极大地减少 APK 占用的空间。 矢量图片在 Android 中以 VectorDrawable 对象的形式表示。借助 VectorDrawable 对象,100 字节的文件可以生成与屏幕大小相同的清晰图片。

不过,系统渲染每个 VectorDrawable 对象需要花费大量时间,而较大的图片则需要更长的时间才能显示在屏幕上。因此,请考虑仅在显示小图片时使用这些矢量图形。

如需详细了解如何使用 VectorDrawable 对象,请参阅使用可绘制资源。

将矢量图形用于动画图片

请勿使用 AnimationDrawable 创建逐帧动画,因为这样做需要为动画的每个帧添加单独的位图文件,而这会大大增加 APK 的大小。

您应改为使用 AnimatedVectorDrawableCompat 创建动画矢量可绘制资源。

减少原生和 Java 代码

您可以使用多种方法来缩减应用中的 Java 和原生代码库的大小。

移除不必要的生成代码

确保了解自动生成的任何代码所占用的空间。例如,许多协议缓冲区工具会生成过多的方法和类,这可能会使应用的大小增加一倍或两倍。

避免使用枚举

单个枚举会使应用的 classes.dex 文件增加大约 1.0 到 1.4KB 的大小。这些增加的大小会快速累积,产生复杂的系统或共享库。如果可能,请考虑使用 @IntDef 注解和代码缩减移除枚举并将它们转换为整数。此类型转换可保留枚举的各种安全优势。

缩减原生二进制文件的大小

如果您的应用使用原生代码和 Android NDK,您还可以通过优化代码来缩减发布版应用的大小。移除调试符号和不提取原生库是两项很实用的技术。

移除调试符号

如果应用正在开发中且仍需要调试,则使用调试符号非常合适。您可以使用 Android NDK 中提供的 arm-eabi-strip 工具从原生库中移除不必要的调试符号。之后,您便可以编译发布 build。

避免解压缩原生库

在构建应用的发布版本时,请确保在应用的 build.gradle 文件中将 useLegacyPackaging 设置为 false,以便将未压缩的 .so 文件打包到 APK 中。停用此标志可防止 PackageManager 在安装过程中将 .so 文件从 APK 复制到文件系统,并具有减小应用更新的额外好处。

维护多个精简 APK

APK 可能包含用户下载但从不使用的内容,例如其他语言或针对特定屏幕密度的资源。如需确保为用户提供最小的下载文件,您应该使用 Android App Bundle 将应用上传到 Google Play。通过上传 App Bundle,Google Play 能够针对每位用户的设备配置生成并提供经过优化的 APK,因此用户只需下载运行您的应用所需的代码和资源。您无需再构建、签署和管理多个 APK 以支持不同的设备,而用户也可以获得更小、更优化的下载文件包。

如果您不打算将应用发布到 Google Play,则可以将应用细分为多个 APK,并按屏幕尺寸或 GPU 纹理支持等因素进行区分。

当用户下载您的应用时,他们的设备会根据设备的功能和设置接收正确的 APK。这样,设备不会接收设备所不具备的功能的资源。例如,如果用户具有 hdpi 设备,则不需要您可能会为具有更高密度显示器的设备提供的 xxxhdpi 资源。

如需了解详情,请参阅配置 APK 拆分和维护多个 APK。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3