[译] 我是如何作到在 5 分钟以内将应用大小减小 60% 的

我是如何作到在 5 分钟以内将应用大小减小 60% 的

移动设备的资源老是有限的。有限的电量,有限的存储,有限的处理能力,有限的内存,有限的网络带宽……不管你面对的是 Android 仍是 iOS,这都是真理。javascript

在前几个月,我在开发一个安卓应用 Anti-Theft Screen Lock。当有人尝试用错误的密码解锁设备时,这个应用会经过前置摄像头拍照并播放警示音。若是你想了解更多,这里有 Play 商店的页面:html

Anti-Theft Screen Lock - Android Apps on Google Play前端

在这儿我会教你一些我用来减少应用体积的技巧。这些技巧都简单且易用,会在如今或未来为你提供一些帮助。java


越小越好

做为一个开发者咱们老是更关心应用的性能,设计和用户体验。可是,大多数开发者都忘了(或低估)一件事:应用体积。若是你但愿你的应用能吸引大量用户,这是很是核心的一点。react

市场上大概有 11000 种安卓机型,而其中大部分都是低端机,有限的存储(1GB 到 8GB),甚至用的仍是 2G 或者 3G 网络。这些设备在印度,巴其尔等非洲发展中国家占有大量市场,你能够在这些地方得到大量的用户。android

让你的应用大小保持最佳变得尤为重要。你的应用体积越小,你的用户就有更多的空间来存储他们的视频和图片。说实话,你确定不但愿用户由于“存储空间不足”的提示删除你的应用。ios

若是用户的存储空间不够的话,他们会卸载你的应用。
这些发展中国家用户使用的依然是速度有限的 2G/3G 网。因此,若是你的应用体积太大,将会须要更多的时间来下载(更可能的状况时用户根本不会去下载)。一样的,大多数用户流量有限,用户下载的每一个字节都是在花钱。git

因此,很明显了,应用程序界的真理就是:github

越小越好web


使用 APK Analyser 分解你的 APK

Android Studio 提供了一个有用的工具:APK Analyser。APK Analyser 将会拆解你的应用并让你知道 .apk 文件中的那个部分占据了大量空间。让咱们看一下 Anti-Theft 在没有通过优化以前的截图。

从 Apk Analyser 的输出来看,应用的原大小是 3.1MB。通过 Play 商店的压缩,大体是 2.5MB。

从截图中能够看出主要有 3 个文件夹占据了应用的大多数空间。

  • classes.dex —— 这是 dex 文件,包含了全部会运行在你的 DVM 或 ART 里的字节码文件。
  • res —— 这个文件夹包含了全部在 res 文件夹下的文件。大部分状况下它包含全部图片,图标和源文件,菜单文件和布局。

  • resources.arsc —— 这个文件包含了全部 value 资源。这个文件包含了你 value 目录下的全部数据。包括 strings、dimensions、styles、intergers、ids 等等。


因此,如今你知道 APK 是怎么组成的了。让咱们接着看看该怎么一块块的优化它以减少应用体积。

减少 classes.dex

classes.dex 包含了全部 Java 代码。当你编译你的应用时,gradle 会将你的全部模块里的 .class 文件转换成 .dex 文件并将这些文件合成一个 classes.dex 文件。

若是你很好奇,编译的过程是怎样的,看个人另外一篇博客:The Jack and Jill: Should you use in your next Android Application?

单个的 classes.dex 文件能够容纳大约 64K 方法。若是你达到了这个限制,你必需要在你的工程中启用 multidexing。这将会建立另外一个 classes1.dex 文件去存储剩下的方法。因此 classes.dex 文件数目由你的方法数而定。

你能够看到如今的 “Anti-Theft Screen Lock” 包含 4392 个类和 29897 个方法。这个结果是没有通过混淆的。你有两个默认的混淆文件。

  • proguard-android-optimize.txt
  • proguard-android.txt

就像文件名写的那样,“proguard-android-optimize.txt”是更积极的混淆选项。咱们将这个做为默认的混淆配置。你能够在 /app 目录下的 proguard-rules.pro 里添加自定义的混淆配置。

release {
    //Enable the proguard
    minifyEnabled true
    proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), "proguard-rules.pro"

    //Other parameters
    debuggable false
    jniDebuggable false
    renderscriptDebuggable false
    signingConfig playStoreConfig //Add your own signing config
    pseudoLocalesEnabled false
    zipAlignEnabled true
}复制代码

经过设置 minifyEnabled 为 true,混淆将会移除全部未使用的方法、指令以减少 classes.dex 文件。

这是启用了 minify 以后的 APK。

你能够看到在为每一个模块启用了混淆以后咱们的 classes.dex 大小减少了几乎 50%。同时你能够看到方法数从 29897 降到了 15168(几乎 50%)。恭喜……🎊🎉

体积从 3.1MB 降到了 1.98MB。(缩小约 50%)


减少 res:

下一大块就是 res 文件夹,它包括了全部的图片,raw 文件和 XML。你不能添加/删除/修改你的 XML,由于它们包含了你的布局。可是咱们能够减少图片文件。

  • shrinkResources” 属性将会移除全部在工程中没有用到的资源。在 build.gradle 中像下面这样启用它:
release{
  //...
  //...
  shrinkResources true
  //...
}复制代码
  • resConfigs” 属性将会在构建过程当中移除全部本地化资源。app “Anti-Theft Screen Lock” 只须要支持英语。而不少的支持库均可能有其它语言的本地化文件夹。这些是我不须要的。因此,添加下面的这些代码让应用只支持英语。
defaultConfig {
    //...
    //...
    //...

    //strip other than english resources
    resConfigs "en"
}复制代码
  • 若是你在用 Android Studio 2.3,而且你的应用的最低支持版本大于 18,你可使用 webp 替代 png。webp 图片比 png 体积更小但质量同样。并且 Android 支持 webp。因此你能够在 ImageView 中像加载其它光栅图片同样加载 webp 图片。这不须要改变你的布局。

你能够在工程选择 drawable 和 mipmap 文件夹,右击并选择 convert to webp。这将会打开下面这样的配置弹框。

点击 ok,将会将全部 png 图片转成 webp。若是 webp 图片比 png 更大,Android Studio 将会自动跳过这个文件。

让咱们看下最终效果:

喔!!!res 文件夹从 710KB 降到了 597KB。

体积减少了 105KB。(下降了 16%)

你也能够将图片转为矢量图。可是这样你须要对它的向后兼容性进行一些处理。若是你想了解更多 vector 的相关知识,看看 Chris Banes 的这篇博客


TL;DR:

  • 经过在你的 release build type 中加上下面这些代码启用混淆。
  • 启用 shrinkResources。
  • 经过在 “resConfigs” 里添加须要的资源名移除全部不须要的本地化资源。
  • 将全部图片转为 webp 或者矢量图。

总结:

经过使用上面这些简单的技巧我将应用体积从 3.19MB 降至了 1.89MB。

这些只是最简单的方式,还有不少减少应用体积的方法。可是,你应该始终使用上面这些简单的方法来保证已经尽量的减少了应用体积。

你能够在这儿学习更多的技巧。

记住:越小越好。😉


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOSReact前端后端产品设计 等领域,想要查看更多优质译文请持续关注 掘金翻译计划

相关文章
相关标签/搜索