[译] Android性能优化:APK瘦身方式大汇总

你们都知道开发中应用程序的性能是很是重要的,将直接影响用户的体验,可是性能优化是个老生常谈的问题,咱们须要慢慢来,本篇文章将从如何减小APK的大小开始,来提高Android App的性能,这里只是列举了一些方式方法,读者可根据自身应用须要对本身的APK进行相应处理。html

原地址 developer.android.com/topic/perfo…android

用户常常会避免下载看起来太大的应用程序,尤为是在设备链接到2G和3G网络或付费网络的应用市场内部。这篇文章讲述如何减小您的应用程序APK的大小,以便使更多的用户下载您的应用程序。git

理解APK文件结构

在讨论如何下降您的应用程序的大小以前,理解一个应用程序的APK的文件结构它是很是有帮助的。一个APK文件包含一个ZIP归档,主要包含您的应用程序的全部文件。这些文件包括Java类文件,资源文件,和包含编译的文件资源。github

一个APK包含以下目录:web

  • META_INF/:包含CERT.SFCERT.RSK 签名文件,以及MANIFEST.MF清单文件。安全

  • assets/:包含应用程序的资产,应用程序可使用一个AssetManager对象检索。性能优化

  • res/:包含不能被编译进resources.arsc文件的资源。bash

  • lib/:包含编译后的代码,是特定于处理器的软件层。这个目录包含为每一个平台类型分配的子目录,像armeabi,armeabi-v7a,arm64-v8a,x86,x86_64,和mips。 可是优化 APK还包含如下文件。其中,只有AndroidManifest.xml是强制性的。服务器

  • resources.arsc:包含编译的资源。这个文件包含来自文件夹res/values/下全部配置的XML内容。包装工具提取这个XML内容,将它编译成二进制形式而且归档这些内容。这个内容包括语言字符串和样式以及路径下不存在于resources.arsc文件的内容,好比布局文件和图片。网络

  • classes.dex:包含DEX文件中编译的类能够被 Dalvik/ART 虚拟机理解的格式。

  • AndroidManifest.xml:包含Android的核心清单文件。这个文件列出了应用的名称,版本,访问权限,以及引用的库文件的应用程序。文件使用Android的二进制XML格式。

减小资源的数量和大小

APK的大小影响应用程序的加载速度,对内存的使用,和它对电量的消耗。一个使您的APK较小的简单方式是减小它包含资源的数量和大小。特别是,您能够移除应用程序再也不使用的资源,和您可使用可拉伸的Drawable图像文件。本节讨论这些方法以及其余几个方法都是经过减小您的应用程序使用的资源来减小您的APK整体规模。

移除不使用的资源

Android Studio 内部包含一个静态代码分析器lint工具,使用它能够检索资源文件夹res/,找出您的代码不引用的资源。当lint工具在您的工程中发现一个潜在的未被使用的资源,它会打印一条消息就像下面的例子。

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

⚠️:lint工具不能扫描assets/目录,经过反射引用assets,或您链接库文件到您的应用。同时,它不会删除资源;只提醒你他们的存在

您的代码依赖的库文件或许包含不被使用的资源。若是在您的build.gradle构建文件中启用shrinkResources,它表示Gradle会自动删除这些资源。

android {
    // Other settings

    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
复制代码

为了使用shrinkResources,你必须启用代码压缩。在构建过程当中,首先ProGuard删除未被使用的代码可是闲置未被使用的资源。而后Gradle移除未被使用的资源。

关于ProGuard和其它Android Studio提供的途径,帮助您减小APK大小的更多的信息,能够参照Shrink Your Code and Resources

在Android Gradle插件0.7和更高版本上,您能够声明您的应用程序支持的配置。Gradle经过使用resConfigresConfigs类别以及默认配置defaultConfig选项,去构建系统。而后构建系统能够防止不受支持的配置的资源,出如今APK文件中,从而减小APK文件的大小。关于此功能的更多信息,能够查看 Remove unused alternative resources

最小化来自于外部库资源的使用

当咱们开发一个Android应用程序时,您一般使用外部库来提升应用程序的可用性和多功能性。例如,您能够引用Android Support Library来改善应用程序在旧设备上的用户体验,或者您能够在您的应用程序内部使用Google Play Services来检索文本,对其进行自动翻译。

若是一个库被设计用于一个服务器或桌面。它可能包括许多您的应用程序不须要的对象和方法。为了作到只包括您须要的部分,若是库的证书容许您能够编辑该库的文件。您还可使用一个替代的方法,移动指定的功能模块到您的应用程序。

⚠️:ProGuard能够清除一些没必要要的代码导入库,可是不能移除一个库庞大的内部依赖关系。

仅仅支持特定密度

Android支持一组很是大的设备,包括各类各样的屏幕密度。在Android 4.4(API级别19)和更高版本,该框架支持各类密度:ldpimdpitvdpihdpixhdpixxhdpixxxhdpi。即便Android支持全部的这些密度,您也不须要为每一个密度导出相应的资源。

若是您知道只有一小部分用户的设备拥有特定的密度,这些密度是否须要包括到您的应用程序中那是值得考虑的。对应于一个特定的屏幕密度,若是您不包括相应的资源,Android会根据其它屏幕密度,找寻与之相近的现有资源。

若是您的应用程序只须要按比例缩小的图像,在drawable-nodpi/文件下放置惟一图像便可,这样您能够节省更多的空间。咱们建议每个应用程序包括至少一个xxhdpi图像变体。

关于屏幕密度的更多信息,能够参见Screen Sizes and Densities

使用drawable对象

一些图像不要求一个静态的图片资源;框架能够在运行时动态画出图像。Drawable对象(<shape>在XML内)在您的APK内部能够占用少许的空间。另外,XMLDrawable对象产生的单色图像符合材料设计(material design)的指导方针。

减小资源

对于一个图像的变化,您能够包括一个单独的资源,如着色、阴影或旋转版本相同的图像。无论怎样,咱们建议您重用相同的一组资源,在运行时根据须要自定义它们。

Android 提供了一些工具来改变资源的颜色,在Android5.0(API21)和更高的版本上可使用android:tint和tintMode属性。对于较低的平台版本,可使用ColorFilter类。

对于一种资源通过旋转能够获得另外一种资源,您能够只导入一个。下面的代码片断提供了一个示例:将一个“thumb up”绕轴旋转180度转变成“thumb down”:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_thumb_up"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromDegrees="180" />
复制代码

图像经过代码渲染

您还能够经过程序渲染您的图片,进而减小您的APK大小。程序渲染腾出空间,由于您不须要存储图片到你的APK文件中。

Crunch PNG 文件

在构建过程当中,aapt工具可使用无损压缩方式优化放置在res/drawable/目录下的图像资源,进而下降图片空间占用。例如,the aapt tool can convert a true-color PNG that does not require more than 256 colors to an 8-bit PNG with a color palette(这句很差翻译).这样转换以后,相同质量的图像会占用更小的内存。

请注意,aapt拥有如下限制:

  • aapt不能压缩asset/目录下的PNG文件。
  • aapt工具优化图像文件须要使用256或更少的颜色。
  • aapt工具可能屡次优化已经压缩过的PNG文件。为了不这个您能够在Gradle文件中使用cruncherEnabled标志禁用对PNG文件的处理。
aaptOptions {
    cruncherEnabled = false
}
复制代码

压缩 PNG 和 JPEG 文件

您能够在不丢失图像质量的状况下使用工具减小 PNG 文件的大小,像 pngcrush, pngquant, or zopflipng。全部这些工具能够减小PNG文件的大小,同时保留感知的图像质量。

pngcrush工具是特别有效的:这个工具遍历PNG过滤器和zlib(Deflate)参数,使用过滤器和参数的组合压缩图像。而后选择压缩效果最好的配置输出(It then chooses the configuration that yields the smallest compressed output)。

为了压缩 JPEG 文件,你可使用工具好比: packJPG and guetzli.

使用 WebP 格式文件

针对Android 3.2(API级别13)和更高版本,您还可使用WebP图像格式文件,而不是使用 PNG 和 JPEG 文件。WebP格式提供了有损压缩(如JPEG)以及透明度(如PNG),相较于JPEG或PNG它能够提供更好的压缩。

使用Android Studio,您能够转换存在的 BMP,JPG,PNG 或 静态的GIF图像为 WebP格式。更多的信息,请参考 Create WebP Images Using Android Studio

⚠️:谷歌市场接受APK的启动图标只能是PNG格式。

使用矢量图

您可使用矢量图形建立分辨率无关图标和其余可伸缩的媒体。使用这些图形能够大大减小你的APK大小。在Android中,矢量图表示为VectorDrawable对象。VectorDrawable对象,一个100字节的文件能够用于呈现屏幕大小的图像。

然而,系统须要大量的时间来呈现每一个VectorDrawable对象,且图像越大呈现到屏幕上所须要的时间越长。所以,考虑只有当显示小图像时使用这些矢量图形。

更多的关于VectorDrawable对象如何工做的信息,能够参考Working with Drawables

使用矢量图形动画图像

不能使用 AnimationDrawable对象去建立帧动画,由于这样作对于每一帧动画都须要包括一个单独的bitmap文件,这大大增长APK的大小。

您应该使用AnimatedVectorDrawableCompat去建立矢量动画

减小 native 和 Java 代码

这里有几种方法能够用来减小在您的应用程序中 Java 和 native 代码库的大小。

移除没必要要生成的代码

肯定了解由工具自动生成的任何代码的足迹(Make sure to understand the footprint of any code which is automatically generated)。例如,许多协议缓冲工具生成过多的方法和类,它可使您的应用程序大小提高两倍或三倍。

避免使用枚举

一个枚举可使您的应用程序的classes.dex文件增长约 1.0 到 1.4 KB大小。对于复杂系统或共享库这些添加能够迅速增大此文件。若是可能的话,能够考虑使用@IntDef注解和ProGuard去剥离枚举,取出将它们转换为整数。这种类型的转换保存全部的枚举类型是安全可靠的。

减小本地二进制文件的大小

若是您的应用程序使用本地代码和Android NDK,你也能够减小你的应用程序的发布版本的大小,以优化你的代码。两个有用的技术去除调试符号而不是提取本地库。

移除调试符号

使用调试符号的意义,在于您的应用程序在开发过程当中仍然须要调试。使用arm-eabi-strip工具(Android NDK 提供),从本地库删除没必要要的调试符号。 以后,您能够编译发布构建。

避免提取本地库

在构建应用程序的发布版本时,若是您在你的应用程序的清单文件中,元素标签下设置属性以下android:extractNativeLibs="false",则APK包将不会压缩.so文件。禁用这个标志能够在应用的安装过程当中,阻止PackageManager从您的APK拷贝.so文件到文件系统,这样作的好处是让您更新您的应用程序更小。

维护多个精简的 APKS

APK可能包含一些用户下载但从未使用的内容,如区域或语言信息。为用户建立一个最小的下载,你能够将您的应用程序分割成几个apk,分化的因素如屏幕大小或GPU硬件的支持。

当用户下载您的应用程序,他们的设备基于设备的功能和设置接收到正确的APK。这种方式,设备没有接收到资产设备没有的功能。例如,若是用户拥有一个hdpi设备,他们不须要相对于更高密度的设备包括的xxxhdpi资源。

更多相关信息,请参考 Configure APK SplitsMaintaining Multiple APKs

若果您以为写得还不错的话,请抬手点个赞吧😜。

相关文章
相关标签/搜索