Android的APK全面瘦身

随着APK功能越来越多、越来越复杂,APK的体积也变得越来越大。当用户去看APK描述时,惊叹:哇!这么多功能,赶紧下载来玩一下。但用户真正点击下载后,发现APK体积这么大,擦!如果没WIFI,下载又耗流量,安装又占内存。经过衡量后,用户可能选择终止下载,这样一来很容易造成用户流失。为了更好用户体验,我们得保证功能多样化的同时,APK体积又足够小。那么,让我们共同探讨下如何对APK进行全面瘦身。

理解APK结构

APK文件由ZIP文档组成,包含你应用程序的所有文件。这些文件包括:java类文件、资源文件和编译资源。

APK包含以下目录:

META-INF/:包含CERT.SF和CERT.RSA签名文件,也包含MANIFEST.MF文件;

assets/:包含app的assets,可以通过AssetManager对象来检索;

res/:包含没有编译进resource.arsc文件的资源;

lib/:包含编译代码,各种平台架构:armeabi,armeabi-v7a,armeabi-v8a,x86,x86_64,mips;

resource.arsc:包含编译资源,打包工具抽取XML内容,编译成二进制格式,并且保存起来;

class.dex:编译成DEX格式文件,让ART/Dalvik虚拟机能够识别;

AndroidManifest.xml:包含Android核心的manifest文件,四大组件、包名、版本号、版本名称、权限等等;

移除无用资源代码

Android Studio自带的lint工具,用于静态代码分析,检查你/res目录下的没有引用的文件。当lint工具在你的工程发现潜在的无用代码时,会打印如下信息:

res/layout/preferences.xml: Warning: The resource R.layout.preferences appears
    to be unused [UnusedResources]
另外,在gradle.build配置文件添加代码混淆:

android {
    buildTypes {
        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
只需支持特定像素密度

Android支持各种型号设备,每种型号的屏幕密度不同。在Android4.4及以上,支持分辨率包括:ldpi、mdpi、hdpi、xhdpi、xxhdpi和xxxhdpi。我们没必要适配所有设备,只需要选择特定分辨率进行适配,这样可以减少图片资源的引入。

减少动画帧数

帧动画对APK体积影响很大。例如,原来引入30帧动画,可以在不影响动画效果前提下,适当减少帧数。

使用Drawable对象

一些图片并不需要静态图片资源,这种情况下,我们可以使用Drawable代替静态图片。这样可以减少图片资源。

复用资源

可以为图像的变化添加单独资源,比如:浅色、形状、旋转等。但是,推荐复用相同资源,在运行时再自定义改变。Android提供几种方式来改变颜色,Android5.0以上,可以使用android:tint和android:tintMode。如果是Android5.0以下,可以采用ColorFilter类进行设置。你也可以删除原有旋转效果资源,使用相同效果更加简单方式实现。以下代码用于实现箭头的展开与收起,通过把原图旋转180°:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_arrow_expand"
    android:fromDegrees="180"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="180" />
优化PNG文件

aapt工具可以在编译过程使用无损压缩方式,优化res/drawable目录的图片资源。比如,aapt工具可以使用颜色调色板,不需要256种color情况下,把true-color的PNG图片转成8位。这样图片质量不变,但是所占内存更小。你需要在gradle进行如下配置:

aaptOptions {
    cruncherEnabled = false
}
压缩PNG和JPEG文件

你可以使用有损压缩工具:pngcrush、pngquant或者zopflipng,对PNG文件进行压缩。可以使用packJPG工具对JPEG文件进行压缩。

webP格式用起来

在你的图片中,你可以使用webP格式代替PNG或者JPEG。webP提供有损压缩(像JPEG一样),也提供透明度处理(像PNG一样)。但是,可以压缩效果比PNG和JPEG好。你可以在android Studio里把PNG或者JPEG格式图片转换成webP格式,选中图片右击,最后一栏


看下webP与jpg对比,图片质量相同,但webP格式所占内存要小一点:


使用矢量图

你可以使用矢量图创建独立分辨率的图标,使用这些图片可以显著减少你APK体积。在Android中,矢量图是以VectorDrawable对象来表示。使用矢量图,100个字节的文件可以生成屏幕大小的清晰图像。具体用法如下:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
     android:height="64dp"
     android:width="64dp"
     android:viewportHeight="600"
     android:viewportWidth="600" >
     <group
         android:name="rotationGroup"
         android:pivotX="300.0"
         android:pivotY="300.0"
         android:rotation="45.0" >
         <path
             android:name="v"
             android:fillColor="#000000"
             android:pathData="M300,70 l 0,-70 70,70 0,0 -70,70z" />
     </group>
 </vector>
但是,矢量图需要很长时间来渲染。这算是以时间换空间的代价。考虑到这点,只在图片比较小的情况下,才采用矢量图。

移除枚举

一个枚举变量可以在class.dex文件里增加1.0到1.4KB。这些额外体积会迅速增加系统和共享库的复杂性。可以的话,使用@IntDef和ProGuard把枚举变量移除掉,并且把他们转换成整型。


大半夜写博客的好处是安静,虽然有点困。希望这篇文章可以帮助大家成功实现APK瘦身,如果有好的建议大家也可以分享下。程序员的最终目标:让代码变得更加简洁,让用户体验变得更好!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

徐福记456

您的鼓励和肯定是我创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值