深入探索Android包体积优化(匠心制作下)成为一名优秀的Android开发,需要一份完备的知识体系,在这里,

通常来说,当应用处于成长期的中后阶段时,才会考虑去做系统的包体积优化,因此,只有在这个阶段及之后,包体积优化带来的收益才是可观的。

众所周知,Android构建工具链中使用了AAPT/AAPT2工具来对资源进行处理,Manifest、Resources、Assets的资源经过相应的ManifesMerger、ResourcesMerger、AssetsMerger资源合并器将多个不同moudule的资源合并为了MergedManifest、MergedResources、MergedAssets。然后,它们被AAPT处理后生成了R.java、ProguardConfiguration、CompiledResources。如下图左上方所示:

其中ProguardConfiguration、CompiledResources的作用如下所示:

APK的资源主要包括图片、XML,与冗余代码一样,它也可能遗留了很多旧版本当中使用而新版本中不使用的资源,这点在快速开发的App中更可能出现。我们可以通过点击右键,选中Refactor,然后点击RemoveUnusedResource=>preview可以预览找到的无用资源,点击DoRefactor可以去除冗余资源。如下图所示:

需要注意的,AndroidLint不会分析assets文件夹下的资源,因为assets文件可以通过文件名直接访问,不需要通过具体的引用,Lint无法判断资源是否被用到。

此外,当我们通过shrinkResourcestrue来开启资源压缩,资源压缩工具只会把无用的资源替换成预定义的版本而不是移除。那么,如何高效地对无用资源自动进行去除呢?

我们可以在Android构建工具执行package${flavorName}Task之前通过修改CompiledResources来实现自动去除无用资源,具体的实现原理如下:

通过查看Zip格式资源包中每个ZipEntry的CRC-32checksum来寻找被替换的预定义资源,预定义资源的CRC-32定义在ResourceUsageAnalyze中,如下所示:

具体的实现代码如下所示:

aaptOptions{cruncherEnabled=false}此外,我们还要注意对图片格式的选择,对于我们普遍使用更多的png或者是jpg格式来说,相同的图片转换为webp格式之后会有大幅度的压缩。对于png来说,它是一个无损格式,而jpg是有损格式。jpg在处理颜色图片很多时候根据压缩率的不同,它有时候会去掉我们肉眼识别差距比较小的颜色,但是png会严格地保留所有的色彩。所以说,在图片尺寸大,或者是色彩鲜艳的时候,png的体积会明显地大于jpg。

下面,我们就着重讲解下如何针对性地选择图片格式。

在GoogleI/O2016中,讲到了如何选择相应的图片格式。首先,如果能用VectorDrawable来表示的话,则优先使用VectorDrawable;否则,看是否支持WebP,支持则优先用WebP;如果也不能使用WebP,则优先使用PNG,而PNG主要用在展示透明或者简单的图片,对于其它场景可以使用JPG格式。简单来说可以归结为如下套路:

VD(纯色icon)->WebP(非纯色icon)->Png(更好效果)->jpg(若无alpha通道)

用图形化的形式如下所示:

最后,如果要在项目中使用VD,则以下几点需要着重注意:

与VD类似,还有一种矢量图标iconFont,即字体图标,图标就在字体文件里面,它看着是个图标,其实却是个文字。它的优势有如下三个方面:

它的缺点也很明显,大致有如下三个方面:

如果不是纯色小icon类型的图片,则建议使用WebP。只要你的App的minSdkVersion高于14(Android4.0+)即可。WebP不仅支持透明度,而且压缩率比JPEG更高,在相同画质下体积更小。但是,只有Android4.2.1+才支持显示含透明度的WebP,此外,它的兼容性不好,并且不便于预览,需使用浏览器打开。

此外,在Gradle构建APK的过程中,我们可以判断当前App的minSdkVersion以及图片文件的类型来选用是否能使用WebP,代码如下所示:

然后,我们来讲解下资源如何进行混淆。

同代码混淆类似,资源混淆将资源路径混淆成单个资源的路径,这里我们可以使用AndroidResGuard,它可以使冗余的资源路径变短,例如将res/drawable/wechat变为r/d/a。

下面,我们就使用AndroidResGuard来对资源进行混淆。

APK生成目录如下:

对于AndResGuard工具,主要有两个功能,一个是资源混淆,一个是资源的极限压缩。下面,我们就来分别了解下它们的实现原理。

资源混淆工具主要是通过短路径的优化,以达到减少resources.arsc、metadata签名文件以及ZIP文件大小的效果,其效果分别如下所示:

AndResGuard使用了7-Zip的大字典优化,APK的整体压缩率可以提升3%左右,并且,它还支持针对resources.arsc、PNG、JPG以及GIF等文件进行强制压缩(在编译过程中,这些文件默认不会被压缩)。那么,为什么Android系统不会去压缩这些文件呢?主要基于以下两点原因:

我们可以通过内联RField来进一步对代码进行瘦身,此外,它也解决了RField过多导致MultiDex65536的问题。要想实现内联RField,我们需要通过Javassist或者ASM字节码工具在构建流程中内联RField,其代码如下所示:

我们可以把所有的资源文件合并成一个大文件,而一个大资源文件就相当于换肤方案中的一套皮肤。它的效果比资源混淆的效果会更好,但是,在此之前,必须要解决解析资源与管理资源的问题。其相应的解决方案如下所示:

我们需要根据App目前所支持的语言版本去选用合适的语言资源,例如使用了AppCompat,如果不做任何配置的话,最终APK包中会包含AppCompat中所有已翻译语言字符串,无论应用的其余部分是否翻译为同一语言。对此,我们可以通过resConfig来配置使用哪些语言,从而让构建工具移除指定语言之外的所有资源。同理,也可以使用resConfigs去配置你应用需要的图片资源文件类,如"xhdpi"、"xxhdpi"等等,代码如下所示:

android...defaultConfig{ ...resConfigs"zh","zh-rCN"resConfigs"nodpi","hdpi","xhdpi","xxhdpi","xxxhdpi"}...}此外,我们还以利用DensitySplits来选择应用应兼容的屏幕尺寸大小,代码如下所示:

android{...splits{density{enabletrueexclude"ldpi","tvdpi","xxxhdpi"compatibleScreens'small','normal','large','xlarge'}}...}9、尽量每张图片只保留一份比如说,我们统一只把图片放到xhdpi这个目录下,那么在不同的分辨率下它会做自动的适配,即等比例地拉伸或者是缩小。

我们可以将一些图片资源放在服务器,然后结合图片预加载的技术手段,这些既可以满足产品的需要,同时可以减小包大小。

如设定统一的字体、尺寸、颜色和按钮按压效果、分割线shape、selector背景等等。

对于主要由C/C++实现的NativeLibrary而言,常规的优化方式就是去除Debug信息,使用C++_shared等等。下面,对于So瘦身,我们看看还有哪些方案。

So是Android上的动态链接库,在我们Android应用开发过程中,有时候Java代码不能满足需求,比如一些加解密算法或者音视频编解码功能,这个时候就必须要通过C或者是C++来实现,之后生成So文件提供给Java层来调用,在生成So文件的时候就需要考虑生成市面上不同手机CPU架构的文件。目前,Android一共支持7种不同类型的CPU架构,比如常见的armeabi、armeabi-v7a、X86等等。理论上来说,对应架构的CPU它的执行效率是最高的,但是这样会导致在lib目录下会多存放了各个平台架构的So文件,所以App的体积自然也就更大了。

因此,我们就需要对lib目录进行缩减,我们在build.gradle中配置这个abiFiliters去设置App支持的So架构,其配置代码如下所示:

defaultConfig{ndk{abiFilters"armeabi"}}一般情况下,应用都不需要用到neon指令集,我们只需留下armeabi目录就可以了。因为armeabi目录下的So可以兼容别的平台上的So,相当于是一个万金油,都可以使用。但是,这样别的平台使用时性能上就会有所损耗,失去了对特定平台的优化。

看到上图中的libimagepipeline_x86.so,下面我们就以这个so为例来写写加载它的伪代码,如下所示:

在Android4.3(API17)之前,单个进程加载的SO数量是有限制的,在Google的linker.cpp源码中有很明显的定义,如下图所示:

至此,可以看到,FaceBook出品的Buck同ReDex一样,里面的功能都十分强大,Buck除了实现LibraryMerge和Relinker功能之外,还实现了三大功能,如下所示:

如果有相应需求或对Buck感兴趣的同学可以去看看它们的实现源码。

我们需要回顾过去的业务,合理地去评估并删除无用或者低价值的业务。

如果所有的功能都不能移除,那就可能需要去转变开发模式,比如可以更多地采用H5、小程序这样开发模式。

对于应用包体积的监控,也应该和内存监控一样,去作为正式版本的发布流程中的一环,并且应该尽量地去实现自动化与平台化。(这里建议任何大于100kb的功能都需要审批,特别是需要引入第三方库时,更应该慎重)

包体积的监控,主要可以从如下三个纬度来进行:

瘦身优化是性能优化当中不那么重要的一个分支,不过对于处于稳定运营期的产品会比较有帮助。下面我们就来看看对于瘦身优化有哪些常见问题。

我们在回答的时候要注意一些可操作的干货,同时注意结合你的项目周期。主要可以从以下三点来回答:

在项目初期,我们一直在不断地加功能,加入了很多的代码、资源,同时呢,也没有相应的规范,所以说,UI同学给我们很多UI图的时候,都是没有经过压缩的图片,长期累积就会导致我们的包体积越来越大。到了项目稳定期的时候,我们对各种运营数据进行考核,发现APK的包大小影响了用户下载的意愿,于是我们就着手做包体积的优化,我们采用的是AndroidStudio自带的AnalyzeAPK来做的包体积分析,主要就是做了代码、资源、So等三个方面的重点优化。

首先,针对于代码瘦身,第一点,我们首先使用Proguard工具进行了混淆,它将程序代码转换为功能相同,但是不容易理解的形式。比如说将一个很长的类转换为字母a,同时,这样做还有一个好处,就是让代码更加安全了。第二点呢,我们将项目中使用到的一些第三方库进行了统一,比如说图片库、网络库、数据库等,不允许项目中出现功能相同,但是却实现不一样的库。同时也做了规范,之后引入的三方库,需要去考量它的大小、方法数等,而且呢,如果只是需要一个很大库的一个小功能,那我们就修改源码,只引入部分代码即可。第三点,我们将项目中的无用代码进行了删减,我们使用了AOP的方式统计到了哪些Activity以及fragment在真实的场景下没有用户使用,这样你就可以删除掉了。对于那些不是Activity或者是Fragment的类,我们切了很多类的构造函数,这样你就可以统计出来这些类在线上有没有真正被调用到。但是,对于代码的瘦身效果,实际上不是很明显。

接下来,我们做了资源的瘦身。首先,我们移除了项目当中冗余的资源文件,这一点在项目当中一定会遇到。然后,我们做了资源图片的压缩,UI同学给我们资源图片的时候,需要确认已经是压缩过的图片,同时,我们还会做一个兜底策略,在打包的时候,如果图片没有被压缩过,那我们就会再来压缩一遍,这个效果就非常的明显。对于资源,我们还做了资源的混淆,也就是将冗余的资源名称换成简短的名字,资源压缩的效果要比代码瘦身的效果要好的多。

最后,我们做了So的瘦身。首先,我们只保留了armeabi这个目录,它可以兼容别的CPU架构,这点的优化效果非常的明显。移除了对别的架构适配So之后,我们还做了另外一个处理,对于项目当中使用到的视频模块的So,它对性能要求非常高,所以我们采用了另外一种方式,我们将所有这个模块下的So都放到了armeabi这个目录下,然后在代码中做判断,如果是别的CPU架构,那我们就加载对应CPU架构的So文件即可。这样即减少了包体积,同时又达到了性能最佳。最后,通过实践可以看出So瘦身的效果一般是最好的。

主要可以从以下两个方面来进行回答:

在大型项目中,最好的方式就是结合CI,每个开发同学在往主干合入代码的时候需要经过一次预编译,这个预编译出来的包对比主干打出来的包大小,如果超过阈值则不允许合入,需要提交代码的同学自己去优化去提交的代码。此外,针对项目的架构,我们可以做插件化的改造,将每一个功能模块都改造成插件,以插件的形式来支持动态下发,这样应用的包体积就可以从根本上变小了。

至此,我们可以了解到,如果要想对包体积做更深入的优化,就必须对APK组成,Dex、So动态库以及Resource文件格式,还有APK的编译流程有深入地了解,这样我们才能有足够的内功素养去实现包体积的深度优化。

THE END
1.特殊网名制作软件大全网名app下载网名生成器特殊网名制作软件大全能生成带有特殊符号昵称的软件,比如竖立网名、稀有漂亮符号、麒麟符号、昵称中间一横等特殊符号,非常独特好看,一键即可生成你想要的特殊符号昵称,网名生成器、特殊网名制作、网名大全等软件让你在众多不同的社交网络平台上都是非常适用的,大家可以生成自己专属的网名,结合创意和符号等等,可以让你的文字http://www.downyi.com/key/wangmingzhizuoruanjian/
2.名字随机生成器——让你快速取名在生活中,取名是一项非常重要的任务,名字的好坏将会对你的生活产生很大的影响。但是取好名字并不是一件容易的事情,有的人会花费很长时间才能想出一个满意的名字。为了解决这一问题,今天我们就来介绍一种名字生成器——名字随机生成器。 名字随机生成器是一款非常实用的工具,可以帮助你快速生成适合你的名字。该工具https://www.bamuwu.com/details/2064
3.在线八字易经宝宝取名源码带源码数据(网页+APP+小程序)自然语言处理技术:如分词、词性标注、命名实体识别等,这些技术可以用于名字寓意的解析和生成。 开发工具 开发工具用于辅助开发过程,提高开发效率。在起名源码中,常用的开发工具包括: 版本控制系统:如Git等,用于代码的版本管理和协作开发。 IDE(集成开发环境):如Visual Studio Code、PyCharm等,这些IDE提供了代码编辑、调https://blog.csdn.net/rongtinghua/article/details/144259476
4.在线签名生成器免费,rpa,机器人,自动化艺术签名设计免费版在线生成艺术签名在线生成器2024年9月9日?·?艺术签名在线生成器使用非常方便,只需输入你的名字并选择款式就可以一键生成了,完全免费,不限制次数,你可以完全自由发挥. 最高支持四个字的中文名字设计,如果是 更多内容请查看http://www.kachayv.cn/https://www.wdlinux.cn/html/email/20241211/23845.html
5.[社区]制作一个简单的随机姓名(内附一键粘贴)·GameCreatorGame.player.variable.setString(14002,生成.first() ); 复制 显示全部 复制 之后我们设置一下字符串,让全名=姓+名 点击事件就做完了,你的随机姓名也会存进去 什么你问我确认是干嘛的,那个是关闭界面 咱来运行一下 成功了 如果你想姓和名字分开roll,那就做两个按钮,然后把上面的内容复制对应部分,其实很好分https://www.gamecreator.com.cn/forum/det/3850
6.创作猫全国重名查询,详细教程,简单制作,日入多张创作猫的基础功能:去水印、智能配音、老照片修复等,想必大家都有耳闻。 但是却很少有人知道创作猫还有强大的变现板块:涵盖了小说推文、短剧推广、小程序测试等多种内容。 我之前给侄女取名在网上找灵感,刷视频的时候发现一个全国重名查询的小程序,今天就拆解这个项目的玩法 http://www.hmly8.com/?p=59819
7.创作猫全国重名查询,详细教程,简单制作,日入多张创富道场【vip1188.cn】项目课程资源网:创作猫全国重名查询,详细教程,简单制作,日入多张【揭秘】 创作猫的基础功能:去水印、智能配音、老照片修复等,想必大家都有耳闻。 但是却很少有人知道创作猫还有强大的变现板块:涵盖了小说推文、短剧推广、小程序测试等多种内容。 我之前给侄女取名在网上找灵感,刷视频的时候发https://vip1188.cn/35347.html
8.创作猫全国重名查询,详细教程,简单制作,日入多张创作猫的基础功能:去水印、智能配音、老照片修复等,想必大家都有耳闻。 但是却很少有人知道创作猫还有强大的变现板块:涵盖了小说推文、短剧推广、小程序测试等多种内容。 我之前给侄女取名在网上找灵感,刷视频的时候发现一个全国重名查询的小程序,今天就拆解这个项目的玩法 https://www.midou55.com/79767.html
9.花草名称生成器生成字体分类发现字体简介: 花草名称生成器 Shitzu&Porko_PersonalUseOnly 语言:英文 下载 Novelin Black Italic 语言:英文 下载 SherilynSANS 语言:英文 下载 Liber Grotesque Family Thin 语言:英文 下载 Vicanza 语言:英文 下载 PrincessCards 语言:英文 下载 HumbleNostalgia-Italic 语言:英文 下载 FSP DEMO - Octin Prisonhttp://www.qiuziti.com/fontlist2?id=1041628
10.英文名字在线生成在线生成SDK代码华为云帮助中心为你分享云计算行业信息,包含产品介绍、用户指南、开发指南、最佳实践和常见问题等文档,方便快速查找定位问题与能力成长,并提供相关资料和解决方案。本页面关键词:英文名字在线生成。https://support.huaweicloud.com/topic/212170-1-Y
11.姓名代码在线转换器理想股票技术论坛姓名代码在线转换器是一款方便快捷的工具,能够将中文姓名转换成对应的名称代码或代码转换为中文姓名。使用该转换器可以帮助用户快速查询和查找相应的姓名代码,方便实现个人信息录入、数据处理等操作。无论是需要进行批量转换还是单个转换,该转换器都能够满足用户的需求,https://www.55188.com/tag-3650810.html
12.芋道框架万字详解(前后端分离)若依框架yudao可以看出来芋道开发框架是非常全能的,我也用这个框架开发了三个项目所使用的技术栈后端为SpringCloud,前端使用的是Vue3,数据库主要用的两个,MySQL和postgre,主要使用的是他的代码生成功能,在此需要注意的是芋道开发框架目前只支持MySQL的建表插入语句,其余数据库需要另做更改,我一会会去介绍postgre的使用方式。 https://developer.aliyun.com/article/1576332
13.全网首发,4万字Instagram从0到1流量变现实操手册Instagram名字源自于Instamatic,是柯达从1963年开始销售的一个相机的系列名。 公司位于旧金山,由Kevin Systrom动态会展示你在Instagram上登录过的网址链接和你的在线时长。 2.4 成效分析 Insights Aa该功能以文字形式展现,系统为你生成一张贺卡、动图,以用户互动为目的。 系统会给你推荐背景模板,点击https://www.360doc.cn/article/74163855_1125552299.html
14.微信透明昵称设置,空白名字代码生成教程手机堂1、在公众号手机堂后台回复数字5或者“空白昵称”,会得到一个空白的代码符号 。 2、长按复制空白昵称代码。 3、打开微信进入-我-点击自己头像,进入资料设置页面,把空白符号粘贴到名字一栏,然后点击保存就可以了。 返回对话框打开自己头像刷新一下资料,看看是不是变成空白了,这样就搞定了。 https://www.163.com/dy/article/HD0BIE310511K7NK.html
15.抖音空白昵称()(抖音空白昵称代码复制)只需要输入关键词,就能返回你想要的内容,有小程序、在线网页版、PC客户端和批量生成器 官网:https://ai.de1919.com。 本文目录: 抖音名叫空白昵称什么意思 抖音个人简介怎么空白 抖音空白昵称代码复制 抖音名叫空白昵称什么意思 抖音昵称为空说明这个人是用手机登陆上的抖音,上去之后一直没有给自己在抖音上起https://www.de1919.com/article/580456.html
16.微信昵称怎么设置空白微信空白名字代码接亲网微信昵称怎么设置空白 微信空白名字代码 微信,一款即时跨平台通讯工具,可支持单人,多人在线,给大家提供了不少的便利。里面的功能繁多,可供大家选择也是经常要使用到的东西。但是想必大家也晓得,在每一个社交平台上都会有像现实世界中的名片一样的东西—网名或昵称,有了它,相当于有个代号,最起码别人晓得你是谁,那么https://www.jieqinwang.com/baike/52282.html
17.空白代码复制微信名字游戏3、点击“安卓转换”,之后点击“复制”,返回微信“发现”界面,点击右下角“我”,点击“个人头像”,点击“昵称”,删除原来的昵称,长按复制后,点击右上角“保存”即可。 二、微信空白名字代码 之一步、复制特殊符号,不是一般的空白格式 ,直接打空格是没有用的必须用下面的符号,大家可以直接复制:() https://www.taofang114.com/post/17806.html
18.id单字生成器(单字id转换器)游戏问答一个字的ID其实不值钱id单字生成器,因为可以添加【空白代码】这种字符id单字生成器,比如id单字生成器你打算取“帅”这一个字的名字,取名格式就是【空白字符+帅+空白字符】这样,只要不和别人取过的空白字符格式重复,就能成功修改。 第一种为利用游戏BUG;如之前的改名卡BUG,可以输入空格字符。第二种为利用系统识别https://www.fkw8.com/ask/4990.html
19.空白符号,空白名字制作,空白代码复制,王者荣耀CF吃鸡空白名字生成器王者荣耀空白符号,空白代码,空白网名,王者荣耀空白名字,王者空白名,王者空白名怎么打,空白名字复制,王者荣耀CF吃鸡空白名字生成器http://kongbai.teshufuhao.cn/
20.考生姓名代码在线查询昌1893 猖1894 场1901 尝1902 常1903 长1904 偿1905 肠1906 厂1907 敞1908 畅1909 唱1910 倡1911查询员工表显示员工名字、编号、工资,查询结果以名字为序升序排列 2.查询员工表显示员工名字、编号、CAD图案代码查询 免费文档中心 免费文档中心可免积分在线阅读和下载文档 ?免费文档 ?高等教育 ?高中教育https://m.360docs.net/doc/a113248378.html
21.WordPress引用阿里巴巴矢量图标库添加彩色图标第三步:跳转到我的项目页面(没有跳转的点击–>资源管理–>我的项目)//我的项目自己创建名字 第四步:在我的项目页面有一下按钮—>一般选Symbol 第五步:点击 –>查看在线链接(没有的的话可以点击生成链接) —>点此复制代码(代码例如下面) 代码语言:javascript https://cloud.tencent.com/developer/article/2335425
22.cf空白名字制作生成软件下载散人CF空白名代码生成器v1.0免费绿色版由恋伤制作的cf散人空白名称生成器可以随机生成15000千种不同空白呢称,如生成空白名已被使用,您可以点击重新生成空白名按钮或选择自动生成空白名,知道更改名字成功为止,在自动模式下,将每隔10秒钟自动更换一次空白名并复制至剪切板。 代码生成器空白名CF散人 https://www.jb51.net/game/704145.html
23.在线姓名自动生成器注:长宽可以调整。 在自定义姓氏里输入你的姓氏,N多名字任你选~ 代码:<EMBED height=430 type=application/x-shockwave-flash pluginspage=http://www.macromedia.com/go/getflashplayer width=700 src=http://sm./fl/qiming.swf wmode="transparent" invokeurls="false" quality="high" allowScriptAccess="nevehttp://www.360doc.com/content/12/1007/15/6085160_240040489.shtml