Android 开发者减少 APK 文件大小的提示
已发表: 2015-10-281) ProGuard
诸如 ProGuard 之类的代码压缩工具将显着减小 APK 文件的大小。 该工具可在 sourceforge 获得。 请注意,在应用 ProGuard 后重新测试所有应用程序非常重要,因为它有时可能会改变应用程序的行为。 由于 ProGuard 替换了应用程序符号,为了使代码难以阅读,保留符号映射非常重要,以便在必须调查应用程序中的崩溃时可以将堆栈跟踪转换回原始符号。
2) 去除Debug信息
我建议您从应用程序中删除所有与调试相关的功能。 应用程序一般不会看到或使用这些数据,Android 操作系统也不需要它来运行应用程序。 因此,调试信息只会浪费空间,应该删除。
为此,所有与调试相关的功能都必须包含在条件块中,如下所示:
静态最终调试=假; 如果(调试){ v(标签,“调试……”) }
重要的是在编译时设置调试标志(即声明为静态最终),以便编译器能够完全删除所有调试功能。 创建您自己的调试方法(如下所示)并不是一个好主意,因为对 myDebugPrint() 的调用没有包含在条件块中,这意味着编译器必须在调用类中保留有关 myDebugPrint() 的信息。
公共无效 myDebugPrint() 如果(调试) v(标签,“调试……”); } } … 我的调试打印()
3) 从本机库中删除调试符号如果您的应用程序仍在开发中并且仍需要调试,则使用调试符号是有意义的。 但是,如果在编译发布版本时仍然出现调试符号,并且如果您想删除它们,那么我们建议从本机库(.so 文件)中删除调试符号。 这是使用 Android NDK 中的 arm-eabi-strip 命令完成的。
4)推荐的媒体格式如果您的应用程序严重依赖图像、音频或视频,另一种减少 APK 文件大小的方法是使用某些媒体格式。 我们建议您对图像、音频和视频使用以下媒体格式:
- 视频:使用 H264 AVC。 将视频编码为不大于目标设备屏幕分辨率(如果已知)的分辨率。
- 音频:建议所有音频资源使用 AAC 音频。 与 mp3 或 Ogg Vorbis 相比,AAC 在给定质量下实现了更好的压缩。 绝不应使用 WAV 等原始格式。 使用 WAV 格式的常见原因是解码压缩音频流通常意味着播放时的高延迟。 但是,Android 提供了 Sound Pool API,它使应用程序能够使用压缩的音频流而不会造成高延迟。
- 图像:PNG 或 JPEG。 使用 PNG; 由于它是一种无损格式,因此非常适合纹理和艺术品,因为压缩不会产生视觉伪影。 如果有空间限制,请使用 JPEG 或 PNG 和 JPEG 的组合。 高质量的 JPEG 图像可能适用于大型逼真的图像,JPEG 压缩方案已针对这些图像进行了优化。
- 在不损失质量的情况下优化 PNG 尺寸
如果您使用 PNG 格式,PNG 图像可以减小文件大小而不会损失质量。 为此,请使用 OptiPNG 或 PNGCrush 等工具。 两者都非常适合减少 PNG 文件的大小,同时仍能确保图像质量。 PNGcrush 是一个开源程序,它迭代 PNG 过滤器和 zlib (Deflate) 参数,使用每个参数配置重复压缩图像,并选择产生最小压缩 (IDAT) 输出的配置。 另一方面,OptiPNG 完全在内存中执行试验,并且只将最终输出文件写入磁盘。 此外,它还为用户提供了多种优化预设。
5) 删除未使用的资源另一个需要考虑从 APK 文件中删除的潜在空间浪费是 res 目录中未使用的资源,例如未使用的布局、可绘制对象和颜色。 要检测 APK 中可能被删除的未使用资源,请使用 android-unused-resources 工具。 Android Unused Resources 是一个 Java 应用程序,它将扫描您的项目以查找未使用的资源。
6) 避免重复确保您的应用程序没有重复的功能或重复的资产是避免在 APK 中包含不必要文件的明显方法。 了解您使用哪些 Android API 以及每个 API 提供的完整功能非常重要。 可能是一个 Android API 已经在做另一个 API 的工作。 重复的资产(字符串、位图等)也很浪费空间,而且很容易避免。 在较小程度上,重复的代码也会不必要地增加交付的二进制文件的大小。
7) 减少方法数量Avid Android 开发人员一直面临着他们的应用程序中令人头疼的问题。 应用程序可以拥有的方法数量是有限的。 好吧,它曾经是有限的。 终于,去年 10 月,Google 的好人提供了解决方案,但远非理想。 虽然非常容易实现,但 multidex 解决方案复杂且显着延长了编译时间。 没有停滞不前,从 Lollipop (Android 5.0) 开始,整个 Android 虚拟机发生了革命性的变化,以提供更持久的解决方案,这种解决方案甚至改进了常规编译时间。 然而,就目前而言,Lollipop 解决方案也并不理想。 它要求开发人员仅针对 Lollipop 进行开发,这可能会出现问题,因为大多数应用程序都希望与更广泛的受众兼容,并且可能会担心使用早期 Android 版本中不可用的功能。 所以现在,Lollipop 解决方案是一个很好的未来——Android 解决方案,但在可预见的现在可能不会产生太大影响。 那么在此期间可以做些什么呢? 我们都同意你不应该放弃特性和功能,只是为了避免达到 65K 的限制。 但毫无疑问,最佳实践仍然是减少您的应用程序方法数。 那么,如何在不丢失使您的应用与众不同的小火花的情况下仍然尝试减少方法数呢?
简短概述:“所有这些方法都来自哪里?”
方法计数限制大致为 65K 方法(准确地说是 65,536)。 这听起来是一个巨大的数字。 如果您是一名新手 Android 开发人员,您可能会想“这么多应用程序怎么能这么快达到这个数字?” 你可能有点正确。 自己写这么多方法并不容易。 但是应用程序开发人员不会自己编写整个应用程序。 应用程序开发人员正在使用越来越多的第三方库(SDK - 软件开发工具包),这有助于他们实现某些目标和功能,否则他们必须完全自行开发。 从广告到 GUI 增强,再到社交网络、崩溃报告等等,SDK 提供了广泛的功能和 API,可以节省宝贵的开发时间并帮助您更快地推出应用程序。 但是每个 SDK 都会增加您的方法数量,并且一些 SDK 的功能甚至超出了您的预期。 当然,这不一定是坏事。 然而,致命一击来自谷歌自己。 他们的 Google Play 服务套件是一个包含 28,000 多个方法的大型 SDK。 限制为 65K,这个数字并不低。 许多应用程序开发人员都喜欢使用这个 SDK,因为它打开了通往神奇的 Google 王国的大门,这是一个非常需要的功能,可以为应用程序增加大量价值。 在这篇文章中,我不仅会解释如何有选择地使用 Google Play 服务包,还会告诉你这些包中的每一个都为你的应用程序添加了多少方法。 所以请稳住自己的座位,这将是一段颠簸的旅程。
Google Play 服务游乐场
那么 Google Play Services 实际添加了多少方法呢? 好吧,就像生活中的一切一样,它比一个底线数字要复杂得多。 但是,让我们一步一步来。 Google Play 服务 SDK 实际上包含 19 个不同的 SDK。 使用 Gradle,您可以有选择地选择使用哪些。 您所要做的就是将以下依赖项添加到您的应用程序模块的build.gradle文件中:
依赖{ 编译'com.google.android.gms:play-services:7.5.0' }
7.5.0 是此时发布的最新 GPS 版本。 它在 Android SDK 管理器中标记为修订版 25。 为了选择特定的包,用你想要的任意多的依赖行替换下面的行,指定特定的包。 例如,您只想要 Google Plus、Google Games、Google Ads 和 Google Maps:
依赖{ 编译'com.google.android.gms:play-services-plus:7.5.0' 编译'com.google.android.gms:play-services-games:7.5.0' 编译'com.google.android.gms:play-services-ads:7.5.0' 编译'com.google.android.gms:play-services-maps:7.5.0' }
不太难,但这是第一个问题。 光荣的 19 个 SDK 之一称为 play-services-base。 如果您包含任何 Google Play 服务包,它也会自动添加。 基础包包含多少个方法? 将近 8,000 个(具体数字如下)。
这是第二个问题。 在上面的示例中,我没有只包含 3 个包。 如果你也算上基本包,我什至不只包括 4 个。 事实上,我包括了 5 个包。 为什么? 因为 Google Games 包使用了 Google Drive 包,所以它也被导入了(实际上,Google Ads 还包括一个名为标签管理器的包,但我这里只计算“可选”包)。
所以现在我们开始理解为什么要计算每个 Google Play 服务包向我们的应用程序添加了多少方法有点困难。 包括一个包,并不一定意味着排除其他包。
所以这里是最底层的——你可以添加哪些包,他们添加了多少方法,以及他们带来了哪些其他包来破坏派对。 数据指的是最新版本的 Google Play 服务(7.5.0 / 修订版 25):
方法总数:28,175。您必须承认,其中一些数字确实很残暴。 如果你想要的只是全景包,你不能只得到九种方法,你必须得到近8000个。 难怪有如此多的应用程序接近或超过 65K 的限制。
如果您尝试将其中一些数字相加,它们中的一些似乎有点不一致。 那是因为,Google Play 服务背后的逻辑比看上去要复杂一些。 例如,Google Analytics 包含来自 Google Ads 的单一方法,以获取帐户的广告 ID。
请注意,在计算每个包添加到您的应用程序中的数量时,请务必排除双精度包(例如,不要多次计算基本包)。
您不能有选择地添加所有内容
这是最后的刺痛。 Google Play Services 中有两个无法选择性添加的小包。 搜索包(允许您访问 Google Now API)仅包含 22 种方法。 如果你想使用它,你别无选择,只能添加整个 28,000 多个方法,整个 Google Play 服务。 希望这将在以后的版本中得到修复。
(另一个“无法访问”的包是包含 111 个方法的appstate包,但是现在不推荐使用它,取而代之的是SavedGames ,包含在 google-play-games 包中)。