如果我问一堆开发人员他们的应用程序的大小是什么,我很确定大多数人会查看Android Studio生成的APK文件并告诉我他们的计算机占用了多少磁盘空间。这是最直接的答案,它在技术上是正确的,但也许我应该问更好的问题。考虑这些例如:
- 安装在用户设备上时,您的应用占用了多少空间?
- 用户下载和安装应用程序需要支付多少网络数据?
- 现有用户的应用更新下载大小有多大?
- 运行应用程序的内存占用量(就使用的RAM而言)是多少?
如果您是一名拥有高端手机的开发人员,您可能想知道是否值得花时间优化APK大小...请记住,并非所有设备都具有相同的存储,内存或网络连接。
世界上有些地方用户必须为他们下载的每兆字节数据付费,而且每个角落都没有Wi-Fi热点。
有些设备没有内部存储容量(磁盘空间)来让用户安装他们需要的所有应用程序,这意味着他们必须在安装或更新任何软件之前三思而后行。谁知道,这些可能是你的下一个千万或几百万用户,所以让我们试着让那个APK更小!它将使每个人受益。
当然,考虑到我们都必须处理的各种要求和约束,很难选择一刀切的解决方案。有时,牺牲初始下载大小将加速后续更新。在其他情况下,与直觉相反,在APK中保持文件未压缩可以减少设备上的最终磁盘空间量。我将尝试突出这些权衡并在适用的地方提供解释,但最终由您(开发人员)选择对您的应用和用户有意义的混合技术。
运行时内存占用空间大多超出了本系列文章的范围。所呈现的优化可能对内存使用和性能产生一些小的副作用,包括正面和负面。我会尝试在适用的时候提及任何明显的缺点,但是由读者来衡量你的应用程序的性能特征并进行最后的调用。记住,#permatmatters!
什么是APK
在我开始讨论如何缩小应用程序之前,让我们首先看一下文件格式本身。APK实际上只是一个ZIP存档,包含构成应用程序的文件。通常在APK中,您会找到以下条目:
classes.dex
包含已编译的应用程序代码,转换为Dex字节码。如果您使用multidex来克服65536方法限制,您可能会在APK中看到多个DEX文件。从介绍ART运行时的Android 5.0开始,这些在安装时由提前编译器编译成OAT文件并放在设备的数据分区上。您可以在第2部分:缩小代码中学习如何减小dex代码的大小
RES /
此文件夹包含大多数XML资源(例如布局)和drawables(例如PNG,JPEG)在具有各种限定符的文件夹中,例如-mdpi和-hdpi用于密度,-sw600dp或-large用于屏幕大小和-en,-de,-pl对于语言。请注意,res /中的任何XML文件在编译时都已转换为更紧凑的二进制表示,因此您无法使用APK内部的文本编辑器打开它们。
第3部分:删除未使用的资源显示了如何通过在项目中使用陈旧资源来确保不浪费空间。在第4部分:多APK,ABI和密度分割以及第5部分:通过产品风格的多APK中,我们讨论如何根据硬件特征在多个APK上划分资产,这些APK针对特定设备组。第6部分:图像优化,Zopfli和WebP以及第7部分:图像优化,Shape和VectorDrawables处理各种优化技术,使图像更小。
resources.arsc
一些资源和标识符被编译并展平到此文件中。它通常存储在APK中而不进行压缩,以便在运行时更快地访问。手动压缩此文件似乎很容易获胜,但实际上至少有两个原因并不是一个好主意。一,Play Store压缩任何数据以进行传输和两个,在APK内压缩文件会浪费系统资源(RAM)和性能(尤其是app启动时间)。
第3部分将展示两种方法,通过仅包含对您的应用有意义的语言的字符串,使该文件更加精简。
AndroidManifest.xml中
与其他XML资源类似,您的应用程序清单在编译期间转换为二进制格式。Play商店使用AndroidManifest中包含的某些信息来决定是否可以在设备上安装APK,检查允许的密度或屏幕大小以及可用的硬件和功能(例如触摸屏)。如果要在编译后检查这些Manifest条目,可以使用Android SDK中的aapt工具:
$ aapt dump badging your_app.apk
库/
任何本机库(* .so文件)都将放在以libs /文件夹为目标的ABI(CPU架构,例如x86,x86_64,armeabi-v7a)命名的子文件夹中。通常,它们会在安装时从APK复制到您的/ data分区。但是,由于APK本身在用户设备上不会被更改,因此这实际上会使任何本机库所需的空间翻倍。本文的第8部分(本机库,从APK打开)为Android 6.0+上的此问题提供了解决方案,还可以在旧设备上节省网络带宽。
资产/
此文件夹用于任何不会用作Android类型资源的文件资产。最常见的是字体文件或游戏数据,如关卡和纹理,以及您希望直接作为文件流打开的任何其他应用程序数据。
META-INF /
此文件夹存在于已签名的APK中,并包含APK及其签名中所有文件的列表。目前在Android中签名的方式是,它逐个验证来自存档的未压缩文件内容的签名。
这有一些有趣的后果。由于ZIP文件中的每个条目都是单独存储的,这意味着您可以更改单个文件的压缩级别而无需重新签名。但是,如果您在签名后从归档中删除任何文件,则签名验证将失败。
关于如何创建已签名的APK的另一个注意事项是zipalign工具用作构建的最后一个阶段。如果您手动更改存档的内容,通常您需要重新签名,然后在将APK上传到Play商店之前进行zipalign。
使用Zopfli重新压缩APK(不要这样做)
更新:此前本文包含一个部分,使用更强大的压缩算法Zopfli重新压缩APK中的文件。此功能现在已从Android Studio 2.2中的构建工具中删除,不再推荐使用,因为它可能会影响将Play Store增量更新更小的未来计划。
如果您仍然不相信停止使用Zopfli作为您的APK,读者已经提醒我,某些Android 5.0.1设备可能在阅读Zopfli压缩的APK时遇到问题,甚至可能导致您的应用崩溃。
无论如何,本指南的下一章应该是您的主要关注点,并且比使用Zopfli为APK提供多10倍的节省。
image image
网友评论