Android 最佳实践-性能-减少APK大小

原文链接 https://developer.android.com/topic/performance/reduce-apk-size

减小APK大小

    用户通常避免下载过大的应用,尤其是新兴市场,那里的设备通常链接的是2G/3G网络或者是按流量收费的,这篇文章讲解如何减小你的APP包大小,从而让更多的用户下载。

理解apk的结构

    在讨论如何减小app大小之前,先了解app包的结构对此是很有帮助的。APK包由一个ZIP文档组成,该文档包含了组成APP的所有文件,包括了 java class文件,资源文件,以及由资源编译而来的文件。

    一个APK包含以下的目录

    META-INF/ : 包括CERT.SF 和 CERT.RSA 两个签名文件以及 MANIFAST.MF 清单文件。

    ASSETS/: APP的额外资源文件,这些资源可以通过ASSETMANAGER对象进行检索。

    res:/    包含没有被编译进resouces.arsc的资源文件。

    lib/:    包含了特定与处理器的软件层代码,这个目录下包含有对应平台的子目录比如 armeabi , armeabi-v7a,arm64-v8a,x86,x86-64, mips

    APK文档也包括如下的文件,其中只有Androidmanifest.xml是不可或缺的。

    resource.arsc : 包含编译过的资源,这个文件包含了从 res/value中抽取的各个配置下的XML内容,经过打包后,这些内容转 为 二进制格式并归档,这些内容包括语言字符串和风格,以及那些没有被编译进来的资源的路径,比如布局文件和图像等等。

    classes.dex : 包含了被编译进该文件的class,这种格式可被devik/art虚拟机识别。

    Androidmanifest.xml : 包含了核心组件信息的清单文件,列明了名字,版本,存取权限,这个文件是以android二进制XML保存的

减小资源数量和大小

APK的大小影响APP的加载时间,内存使用和电量消耗。让APK变小的最简单方法之一就是减少资源的数量和大小,尤其是删除没有用到的资源,以及用可缩放drawable对象替换图像文件,这一节将会讨论这个方法已经其他几个能减小apk大小的方法。

去掉没有使用的资源

lint 工具,这是一个被集成到android studio 的静态代码分析器,用来检查res文件夹下未使用到的资源,可以通过指定build.gradle配置中的shrinkResource 为 enable 开启这个功能,gradle会替你自动删除这些资源。

使用该功能前必须先开启shrinkResource,在构建过程中,proguard会去掉未用到的代码,但是不会删除未用到的资源,这些资源稍后由gradle删除。

android gradle 插件0.7及以上,可以声明APP支持的配置,gradle 用 resconfig,resconfigs,defaultconfig 将这些信息传递给构建系统,构建系统会阻止相关未配置的资源出现在APK中,从而减小APK的大小。

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

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

库资源使用最小化

在开发android app的时候,通常会使用外部库来增加可用性和功能。比如你会使用android support libaries 来增加用户在旧平台的体验,或者使用 google play service 来对文本自动翻译。

如果这个库被设计用在桌面或者服务器端,那么它可能包含未用到的方法和对象,为了使用只包含需要用到的代码,你可在许可证允许的情况下编辑库文件或者使用对移动端友好的替代方案来添加所需的功能。

支持特定像素密度

Android 支持很多不同像素密度的设备,android 4.4及以上,framework支持多种密度 ; ldpi, mdpi,tvdpi,xhdpi,xxhdpi,xxxhdpi。

虽然android 支持所有这些像素密度,但是你不需要匹配每一种情况。

如果你知道你的用户中有很小的一部分使用了特定的像素密度,那么考虑是否需要匹配该密度。如果没有与该像素密度匹配的的资源,android 会自动使用其他密度的资源进行缩放处理。

如果你的app只需要 可缩放的图像文件,那么可以把它们放在res/drawable-nodpi/文件夹下来节省更多空间,我们推荐每个APP至少在XXhdpi 下放置一个对应密度的图像

使用 drawable 对象

一些图像并不需要静态图片资源,framework可以在运行期间动态生成图像,drawable 对象会占用apk的一部分空间,此外,XML格式的drawable可以产生满足材料设计语言规范的单色图像。

重用资源

你可以分别使用不同的资源来展示不同的图像变体,着色,阴影,旋转版本的相同图片。但是,我们建议用同一套资源,在运行时根据需要进行客制化。

android 提供了多种工具来改变物体的颜色,android 5.0或者以上 用 android:tint 或者android:tintmode,低版本则用 clolorfilter。

你不需要一张仅仅是旋转了方向的图片,下面的代码片段提供了一个从拇指向上转为向下的旋转180度的例子。

<?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的大小。

处理PNG文件

aapt工具科技通过无损压缩的方式优化放在res/drawable 的图片,比如 aapt工具可以将使用不超过256种颜色的PNG图片转换为8位的PNG图片,转换后的图片质量相同但是内存占用更少。

但是aapt有以下的限制

    不优化assets文件夹下的png图片

    png图片使用的颜色不能超过256种

    aapt会解压已经压缩的png图片,为了防止这样,可以指定cruncherenable 这个标识为disable来禁用该功能

压缩png和jpeg文件

可以通过pngcrush,pngquant,zopflipng 来无损的压缩png文件。其中 pngcrush 特别有效,这个工具通过遍历png过滤器和压缩特征,使用两者的结合来压缩图片,并选择最小的压缩配置进行输出,至于压缩jpeg文件,你可以使用packjpg和guetzli。

使用WebP文件格式

除了png和jpg,还可以使用webp这种格式,webp提供了有损的压缩以及透明度,但是比jpeg和png有更好的压缩效果。你可以使用Android studio 来转化 BMP,JPG,PNG或者静态gif为 Webp格式。

使用向量图形

你可以使用向量图形来创建分辨率独立的图片和可缩放的媒体。使用这些图形可以极大的减小APK的大小。

向量图形在android 中表示为vectorDrawable对象,一个100 比特的vectordrawable对象 可以生成整个屏幕大小的清晰图像。

然而渲染vectorDrawable 会花费系统显著的时间,更大的图像意味着更多的时间,因此应该在只展示小图像的时候使用vectorDrawable。

为动画图片使用向量图形

不要使用animateDrawable来创建逐帧动画,因为每一帧都需要对应的图片,这样会显著的增加APK的大小,你可以使用animateVectorDrawable 来替代。

减少native和java代码

这里有几个方法可以减少native和java代码,删除非必需的生成代码,一个枚举可以给classes.dex增加1k到1.4K大小,这种增加会在复杂系统和共享库内会快速积累。如果可能使用@indef注释将枚举类抽取为整形,这种转换保留了枚举类型所有的安全特点,减少了本地二进制文件大小。如果你使用本地代码和NDK,同样可以通过优化代码减少文件大小。有两个有用的技术,分别是删除调试标记和不提取本地库。

删除调试标记

在开发时使用调试标记是很有用的,使用NDK提供的armeabi-string 工具去除不必要的调试标记,之后再编译用于发布的版本。

避免抽取本地库

在apk中存储未压缩的so文件,以及在manifest文件的application 标签设置 android:extranativelib 为 false ,这样会禁用packagemanager在apk安装过程中将 so文件拷贝到文件系统,这对增量更新有好处,这会减小更新的大小。

维护多个瘦APK

你的apk可能包含了用户下载了而没有使用的资源,比如地区和语言信息。为了使用户的下载量最小你可以分割apk,按屏幕大小,GPU支持的纹理划分。用户下载你的APP时,设备会根据设置和特征收到正确的apk,在这种方式下设备不会收到不支持特征所使用的资源。比如用户的设备是ldpi像素密度,那么他不需要xxxhdpi的资源这些是为更高像素密度的设备准备的。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值