澳门新葡萄京官网注册 5

澳门新葡萄京官网注册App 体积减小

之前写了一篇《APK瘦身实践》侧重于实践和效果对比,后来受徐川老师点拨,建议改写成一篇更全面的瘦身终极杀招大全,深以为然,思考良久,新开一篇。

澳门新葡萄京官网注册 1目录

参考文献:APP终极瘦身指南

指南条例

一、分析app大小

Build > Analyz APK

澳门新葡萄京官网注册 2Paste_Image.png

assets:存放一些配置文件res:资源文件,图片、字符串、xml等classes.dex:字节码文件resources.arsc:编译后的二进制资源文件META-INF:存放的是签名信息,用来保证apk包的完整性和系统的安全。接下来就从classes.dex
, lib , assets
下入手。

第1条:使用一套资源

这是最基本的一条规则,但非常重要。

对于绝大对数APP来说,只需要取一套设计图就足够了。鉴于现在分辨率的趋势,建议取720p的资源,放到xhdpi目录。

相对于多套资源,只使用720P的一套资源,在视觉上差别不大,很多大公司的产品也是如此,但却能显著的减少资源占用大小,顺便也能减轻设计师的出图工作量了。

注意,这里不是说把不是xhdpi的目录都删除,而是强调保留一套设计资源就够了。

二、app 体积减小方案

对于绝大对数APP来说,只需要取一套设计图就足够了。鉴于现在分辨率的趋势,建议取1280
*
720p的资源,放到xxhdpi目录。相对于多套资源,只使用720P的一套资源,在视觉上差别不大,但却能显著的减少资源占用大小。

澳门新葡萄京官网注册 3Paste_Image.png

注意:单套图导致的压缩和放大,对性能的影响显而易见。权衡利弊。

在gradle使用minifyEnabled进行Proguard混淆的配置,可大大减小APP大小:

android { buildTypes { release { minifyEnabled true } }}

在proguard中,是否保留符号表对APP的大小是有显著的影响的,可酌情不保留,但是建议尽量保留用于调试。

在gradle使用shrinkResources去除无用资源,效果非常好。

android { buildTypes { release { shrinkResources true } }}

注意:在release下可能会引发Resources$NotFoundException: Resource ID #0x4,把有用的资源移除掉了。添加了shrinkResources true打完包时候要多测一测。解决办法:方案一放弃使用shrinkResources true方案二参考google关于shrink
resource新建 res/raw/keep.xml后加入如下示例:

<?xml version="1.0" encoding="utf-8"?><resources xmlns:tools="http://schemas.android.com/tools" tools:keep="@layout/l_used*_c,@layout/l_used_a,@layout/l_used_b*,@drawable/icon" tools:discard="@layout/unused2" />

保留文件规则简单介绍,资源文件相对路径加上图片文件名执行 ./gradlew clean
assembleRelease –info|grep “Skipped unused resource”
观察是否安全图片给压缩同时检查解压缩后文件是否为0

大部分应用其实并不需要支持几十种语言的国际化支持。还好强大的gradle支持语言的配置,比如国内应用只支持中文

android { defaultConfig { resConfigs "zh" resConfigs "nodpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi" }}

android打包本身会对png进行无损压缩,所以使用像tinypng这样的有损压缩是有必要的。重点是Tinypng使用智能有损压缩技术,以尽量少的失真换来图片大小的锐减,效果非常好,强烈推荐。

如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。

一种图片文件格式,在相同压缩标准下,webp的有损压缩能比jpg小25-34%。webp支持透明度,压缩比比jpg更高但显示效果却不输于jpg,官方评测quality参数等于75均衡最佳。相对于jpg、png,webp作为一种新的图片格式,限于android的支持情况暂时还没用在手机端广泛应用起来。从Android
4.0+开始原生支持,但是不支持包含透明度,直到Android
4.2.1+才支持显示含透明度的webp,使用的时候要特别注意。使用Fresco支持webp格式图片。如果在API<14的系统也要支持webP图片加入。

// 在API < 14的系统如也要支持 webP图片的话加入compile 'com.facebook.fresco:animated-base-support:0.12.0'// 支持Gif图片,需加入compile 'com.facebook.fresco:animated-gif:0.12.0'// 支持webP图片的动态图,需加入compile 'com.facebook.fresco:animated-webp:0.12.0'// 支持webP图片的静态图,需加入compile 'com.facebook.fresco:webpsupport:0.12.0'

常用的webp转换工具:XnConvet , 智图 , ISparta

如果经过上述步骤之后,你的工程里面还有一些大图,考虑是否有必要维持这样的大尺寸,是否能适当的缩小。事实上,由于设计师出图的原因,我们拿到的很多图片完全可以适当的缩小而对视觉影响是极小的。

有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以考虑用1×1的透明图片覆盖。你可能会有点不舒服,因为你的drawable下竟然包含了一些莫名其妙的名称的1×1图片…

澳门新葡萄京官网注册 41×1像素图片.png

CPU ABI
ARMV5 armeabi
ARMV7 armeabi-v7a
X86 X86
MIPS mips
ARMV8 arm64-v8a
MIPS64 mips64
x86_64 x86_64

Android 目前支持的CPU架构和对应的二进制接口ABI (Application Binary
Interface)

CPU ABI
ARMV5 armeabi
ARMV7 armeabi-v7a
X86 X86
MIPS mips
ARMV8 arm64-v8a
MIPS64 mips64
x86_64 x86_64

基本上armable的so也是兼容armable-v7的,armable-v7a的库会对图形渲染方面有很大的改进,如果没有这方面的要求,可以精简。这里不排除有极少数设备会Crash,可能和不同的so有一定的关系,请大家务必测试周全后再发布。

在当前的Android生态系统中,让app只支持armabi和x86架构就能够了。与第十条不同的是,x86包下的so在x86型号的手机是需要的,如果产品没用这方面的要求也可以精简。建议实际工作的配置是只保留armable、armable-x86下的so文件,算是一个折中的方案。

微信资源压缩打包工具通过短资源名称,采用7zip对APP进行极致压缩实现减小APP的目标,效果非常的好,强烈推荐。详情参考:Android资源混淆工具使用说明原理介绍:安装包立减1M–微信Android资源混淆打包工具建议开启7zip,注意白名单的配置,否则会导致有些资源找不到,官方已经发布AndResGuard到gradle中了,非常方便:

apply plugin: 'AndResGuard'buildscript { dependencies { classpath 'com.tencent.mm:AndResGuard-gradle-plugin:1.1.7' }}andResGuard { mappingFile = null use7zip = true useSign = true keepRoot = false // add <your_application_id>.R.drawable.icon into whitelist. // because the launcher will get thgge icon with his name def packageName = <your_application_id> whiteList = [ //for your icon packageName + ".R.drawable.icon", //for fabric packageName + ".R.string.com.crashlytics.*", //for umeng update packageName + ".R.string.umeng*", packageName + ".R.string.UM*", packageName + ".R.string.tb_*", packageName + ".R.layout.umeng*", packageName + ".R.layout.tb_*", packageName + ".R.drawable.umeng*", packageName + ".R.drawable.tb_*", packageName + ".R.anim.umeng*", packageName + ".R.color.umeng*", packageName + ".R.color.tb_*", packageName + ".R.style.*UM*", packageName + ".R.style.umeng*", packageName + ".R.id.umeng*" ] compressFilePattern = [ "*.png", "*.jpg", "*.jpeg", "*.gif", "resources.arsc" ] sevenzip { artifact = 'com.tencent.mm:SevenZip:1.1.7' //path = "/usr/local/bin/7za" }}

会生成一个andresguard/resguard的Task,自动读取release签名进行重新混淆打包。

对于一些库是按照需要动态的加载,可能在某些版本并不需要,但是代码又不方便去除否则会编译不过。使用provided可以保证代码编译通过,但是实际打包中并不引用此第三方库,实现了控制APP大小的目标。但是也同时就需要开发者自己判断不引用这个第三方库时就不要执行到相关的代码,避免APP崩溃。

特别是在扁平化盛行的当下,很多纯色的渐变的圆角的图片都可以用shape实现,代码灵活可控,省去了大量的背景图片。

相信你的工程里也有很多selector文件,也有很多相似的图片只是颜色不同,通过着色方案我们能大大减轻这样的工作量,减少这样的文件。借助于android
support库可实现一个全版本兼容的着色方案,参考代码:DrawableLess.java

如果你的APP支持素材库的话,考虑在线加载模式,因为往往素材库都有不小的体积。这一步需要开发者实现在线加载,一方面增加代码的复杂度,一方面提高了APP的流量消耗,建议酌情选择

避免重复库看上去是理所当然的,但是秘密总是藏的很深,一定要当心你引用的第三方库又引用了哪个第三方库,这就很容易出现功能重复的库了,比如使用了两个图片加载库:Glide和Picasso。通过查看exploded-aar目录和External
Libraries或者反编译生成的APK,尽量避免重复库的大小,减小APP大小。

同样功能的库在大小上是不同的,甚至会悬殊很大。如果并无对某个库特别需求而又对APP大小有严格要求的话,比较这些相同功能第三方库的大小,选择更小的库会减小APP大小。

过去的一年,插件化技术雨后春笋一样的都冒了出来,这些技术支持动态的加载代码和动态的加载资源,把APP的一部分分离出来了,对于业务庞大的项目来说非常有用,极大的分解了APP大小。因为插件化技术需要一定的技术保障和服务端系统支持,有一定的风险,如无必要(比如一些小型项目,也没什么扩展业务)就不需要了,建议酌情选择。

这条完全取决于业务需求。从统计数据分析砍掉一些没用的功能是完全有可能的,甚至干脆去掉一些花哨的功能出个轻聊版、极速版也不是不可以的。

多次执行上述步骤,你总能发现一些蛛丝马迹,这是一个好消息,不是吗?

redex是facebook发布的一款android字节码的优化工具,需要按照说明文档自行配置一下。

redex input.apk -o output.apk --sign -s <KEYSTORE> -a <KEYALIAS> -p <KEYPASS>

下面我们来看看它的效果,仅redex的话,减小了157k:

澳门新葡萄京官网注册 5Paste_Image.png

先进行微信混淆,再进行 redex
。据反应redex后会有崩溃的现象,这个要留意一下,我这里压缩之后都是可以正常运行的。

三、后续补充如果不是非要用到v7包可以将v7包删掉,可以小1兆

简要评估

指南条例 适用范围 易用性 风险指数 备注
使用一套资源 非极高UI要求的APP
开启minifyEnabled 全部
开启shrinkResources 全部
删除无用的语言资源 非全球国际化应用
使用tinypng有损压缩 非极高UI要求的APP
使用jpg格式 仅限非透明大图
使用webp格式 仅限4.0+,4.2+设备
缩小大图 限允许缩小的大图
覆盖第三库里的无用大图 全部
删除armable-v7包下的so 限允许对极少数设备不兼容
删除x86包下的so 限允许对x86设备不兼容
使用微信资源压缩打包工具 全部 切记要配置白名单
使使用provided编译 全部 容错处理
使用shape背景 全部
使用着色方案 全部
表情在线化 限含表情包的APP
避免重复库 全部
使用更小的库 全部
支持插件化 限扩展性要求高的APP
精简功能业务 限允许精简的APP
Redex优化字节码 全部

前言

第2条:开启minifyEnabled混淆代码

在gradle使用minifyEnabled进行Proguard混淆的配置,可大大减小APP大小:

android {
    buildTypes {
        release {
            minifyEnabled true
        }
    }
}

在proguard中,是否保留符号表对APP的大小是有显著的影响的,可酌情不保留,但是建议尽量保留用于调试。详细proguard的相关的配置和原理可自行查阅。

因公司中有个项目是商城和直播融合在一体的,apk包足足有50多M,因客户推广的需要,公司需要把APK的大小再“减小”一下

第3条:开启shrinkResources去除无用资源

在gradle使用shrinkResources去除无用资源,效果非常好。

android {
    buildTypes {
        release {
            shrinkResources true
        }
    }
}

瘦身前,因为平时就考虑到大小的限制,所以很多工作已经做过了,如下列举现在的状态:

第4条:删除无用的语言资源

大部分应用其实并不需要支持几十种语言的国际化支持。还好强大的gradle支持语言的配置,比如国内应用只支持中文:

android {
    defaultConfig {
        resConfigs "zh"
    }
}

1、开启minifyEnabled

2、开启shrinkResources

3、已经去除不相关的大型库

4、图片和代码已经经历过粗略的一轮清理

第5条:使用tinypng有损压缩

android打包本身会对png进行无损压缩,所以使用像tinypng这样的有损压缩是有必要的。

重点是Tinypng使用智能有损压缩技术,以尽量少的失真换来图片大小的锐减,效果非常好,强烈推荐。

Tinypng的官方网站:

所以现在是在这个基础上再进行一轮瘦身:

第6条:使用jpg格式

如果对于非透明的大图,jpg将会比png的大小有显著的优势,虽然不是绝对的,但是通常会减小到一半都不止。在启动页,活动页等之类的大图展示区采用jpg将是非常明智的选择。

1、tinypng有损压缩

第7条:使用webp格式

webp支持透明度,压缩比比jpg更高但显示效果却不输于jpg,官方评测quality参数等于75均衡最佳。

相对于jpg、png,webp作为一种新的图片格式,限于android的支持情况暂时还没用在手机端广泛应用起来。从Android
4.0+开始原生支持,但是不支持包含透明度,直到Android
4.2.1+才支持显示含透明度的webp,使用的时候要特别注意。

官方介绍:

android打包本身会对png进行无损压缩,不信大家可以看看apk中的图片的大小实际上比你代码工程里的图片要小(针对没进行过无损压缩的那些png图)。

所以,纯粹的进行无损压缩并不会对apk的减小有任何效果,这是我特别想在这里强调的一个经验。

现在大家主流的比较喜欢用的tinypng其实是有损压缩:

https://tinypng.com/

[原文] TinyPNG uses smart lossy compression techniques to reduce the
file size of your PNG files…

[翻译] TinyPNG使用智能有损压缩技术,来减少PNG文件的大小…

通过tinypng确实能在尽量少的损失下再减小apk,如果图片资源多或者大的话,效果还是很明显的。

具体减少多少,因为这个处理过程我们是间隔做的,无法准确给出结果,就按200k~500k算吧。

第8条:缩小大图

如果经过上述步骤之后,你的工程里面还有一些大图,考虑是否有必要维持这样的大尺寸,是否能适当的缩小。事实上,由于设计师出图的原因,我们拿到的很多图片完全可以适当的缩小而对视觉影响是极小的。

2、把png转为jpg,再转为webg

第9条:覆盖第三库里的大图

有些第三库里引用了一些大图但是实际上并不会被我们用到,就可以考虑用1×1的透明图片覆盖。你可能会有点不舒服,因为你的drawable下竟然包含了一些莫名其妙的名称的1×1图片…

⚠️注意:在4.0 ~
4.2.1的设备上无法显示带有透明度的webp,比如,把png转成webp则无法显示,但是如果把png先转成jpg再转成webp则能正常显示了,但会丢失透明度。参考链接:http://developer.android.com/guide/appendix/media-formats.html

第10条:删除armable-v7包下的so

基本上armable的so也是兼容armable-v7的,armable-v7a的库会对图形渲染方面有很大的改进,如果没有这方面的要求,可以精简。这里不排除有极少数设备会Crash,可能和不同的so有一定的关系,请大家务必测试周全后再发布。

3、大图压缩

第11条:删除x86包下的so

与第十条不同的是,x86包下的so在x86型号的手机是需要的,如果产品没用这方面的要求也可以精简。建议实际工作的配置是只保留armable、armable-x86下的so文件,算是一个折中的方案。

如果经过上面的步骤,依然存在大图的话,说明确实图有点大了,可能真的有点大了!所以,要考虑的问题是,是否有必要保证如此的大小?能否缩小?如果这方面能减小的话,apk瘦身的效果必然又会上一个档次。这种情况下的apk的减小是不可估量的。

第12条:使用微信资源压缩打包工具

微信资源压缩打包工具通过短资源名称,采用7zip对APP进行极致压缩实现减小APP的目标,效果非常的好,强烈推荐。

详情参考:
Android资源混淆工具使用说明

原理介绍:
安装包立减1M–微信Android资源混淆打包工具

建议开启7zip,注意白名单的配置,否则会导致有些资源找不到,粗略配置如下,

<?xml version="1.0" encoding="UTF-8"?>
<resproguard>
    <!--defaut property to set -->
    <issue id="property" >
        <seventzip value= "true" />
        <!-- ... -->
    </issue>

    <issue id="whitelist" isactive="true">
        <path value ="com.xxx.yyy.R.drawable.emoji_*" />
        <path value ="com.xxx.yyy.... />
 </issue>

 <issue id ="compress" isactive="true">
        <!-- ... -->
    </issue>
</resproguard>

4、覆盖aar里的一些默认的大图,去除无用的语言资源

第13条:使用provided编译

对于一些库是按照需要动态的加载,可能在某些版本并不需要,但是代码又不方便去除否则会编译不过。

使用provided可以保证代码编译通过,但是实际打包中并不引用此第三方库,实现了控制APP大小的目标。

但是也同时就需要开发者自己判断不引用这个第三方库时就不要执行到相关的代码,避免APP崩溃。

5、删除armable-v7包的so和删除x86包的so

第14条:使用shape背景

特别是在扁平化盛行的当下,很多纯色的渐变的圆角的图片都可以用shape实现,代码灵活可控,省去了大量的背景图片。

6、微信资源压缩打包

第15条:使用着色方案

相信你的工程里也有很多selector文件,也有很多相似的图片只是颜色不同,通过着色方案我们能大大减轻这样的工作量,减少这样的文件。

借助于android support库可实现一个全版本兼容的着色方案,参考代码:
DrawableLess.java

详情参考:Android资源混淆工具使用说明

原理介绍:安装包立减1M–微信Android资源混淆打包工具

第16条:在线化素材库

如果你的APP支持素材库(比如聊天表情库)的话,考虑在线加载模式,因为往往素材库都有不小的体积。这一步需要开发者实现在线加载,一方面增加代码的复杂度,一方面提高了APP的流量消耗,建议酌情选择。

7、proguard深度混淆代码

第17条:避免重复库

避免重复库看上去是理所当然的,但是秘密总是藏的很深,一定要当心你引用的第三方库又引用了哪个第三方库,这就很容易出现功能重复的库了,比如使用了两个图片加载库:Glide和Picasso。通过查看exploded-aar目录和External
Libraries或者反编译生成的APK,尽量避免重复库的大小,减小APP大小。

8、深度清理代码和资源

第18条:使用更小的库

同样功能的库在大小上是不同的,甚至会悬殊很大。如果并无对某个库特别需求而又对APP大小有严格要求的话,比较这些相同功能第三方库的大小,选择更小的库会减小APP大小。

新发现或者新引入的无用图片

这几张图怎么一样

这个类好像没有用

没用的类相关的图片也没用

有些图片可以用着色方案替换

有些图片可以用shape来代替

hdpi里的ic_luancher.png好像也可以删掉

第19条:支持插件化

过去的一年,插件化技术雨后春笋一样的都冒了出来,这些技术支持动态的加载代码和动态的加载资源,把APP的一部分分离出来了,对于业务庞大的项目来说非常有用,极大的分解了APP大小。因为插件化技术需要一定的技术保障和服务端系统支持,有一定的风险,如无必要(比如一些小型项目,也没什么扩展业务)就不需要了,建议酌情选择。

9、proguard去符号表和去除provided关键字

第20条:精简功能业务

这条完全取决于业务需求。从统计数据分析砍掉一些没用的功能是完全有可能的,甚至干脆去掉一些花哨的功能出个轻聊版、极速版也不是不可以的。

在Proguard保留了符号表的

-keepattributes SourceFile,LineNumberTable

PS:友盟上看推广渠道的bug要辛苦一点,手动上传mapping.txt了

去除provided关键字

provided ‘com.android.support:support-annotations:22.0.0’

第21条:重复执行第1到20条

多次执行上述步骤,你总能发现一些蛛丝马迹,这是一个好消息,不是吗?

10、表情包在线化,图标可以使用iconfont管理

在线评估

针对很多朋友的反馈,有必要对条例的适用范围、易用性和风险指数做个粗略的评估,汇总如下,方便大家执行。

指南条例 适用范围 易用性 风险指数 备注
使用一套资源 非极高UI要求的APP
开启minifyEnabled 全部
开启shrinkResources 全部
删除无用的语言资源 非全球国际化应用
使用tinypng有损压缩 非极高UI要求的APP
使用jpg格式 仅限非透明大图
使用webp格式 仅限4.0+,4.2+设备
缩小大图 限允许缩小的大图
覆盖第三库里的无用大图 全部
删除armable-v7包下的so 限允许对极少数设备不兼容
删除x86包下的so 限允许对x86设备不兼容
使用微信资源压缩打包工具 全部 切记要配置白名单
使使用provided编译 全部 容错处理
使用shape背景 全部
使用着色方案 全部
表情在线化 限含表情包的APP
避免重复库 全部
使用更小的库 全部
支持插件化 限扩展性要求高的APP
精简功能业务 限允许精简的APP

11、全版本兼容的着色方案

小结

相信经过上述步骤,一定可以把你的Android
APP极大的瘦身下去。考虑到一定的风险性,建议挑选适合自己的方法就行;同时,我也会跟踪最新的瘦身技巧,及时补充更新。

考虑着色方案主要目的是更方便支持多主题,减轻UI工作量,减少工程里一大堆selector文件等,然后才是,顺便的减小一下apk大小。

12、去除重复库、无用库

13、使用更小的库

14、插件化

发表评论

电子邮件地址不会被公开。 必填项已用*标注