一 、根源
随着业务不断迭代替换 ,App的大小也在快速提升 ,2019年~2022年期间一度超过了117M ,期间我们也做了部分优化如图1红色部分所示,但在做优化的BB Markets蓝莓外汇并且面临着新的增量代码 ,包体积一直连续上升。包体积直接或间接地作用着获取转化率、安装时间、磁盘空间等关键指标,所以投入精力发掘更深层次的安装包体积优化是十分必要的 。根据谷歌商店的内部数据 ,APK体积每下降10M ,平均可提升~1.5%的获取转化率,如图2所示:
图1 京东金融平台2019-2022体积变动流程 (红色部分是期间做的部分优化,但是很快就反弹回去了)
图2 谷歌商店软件转化率提升幅度 / 10M [1]
因此2022年9月开展我们针对金融APP进行了瘦身专项整治 ,在不思考增量的现状,无删减业务代码的现状下实现从117M瘦身至74M ,在本次安装包瘦身流程中我们遇到了不少坑 ,并且也积累了些经验 ,在此复制给大家 。
二 、APK解读
接下来我们会简单解读下 Apk内各组成部分 ,以及 Apk 作为 ZIP ,其标准架构是什么样的,为包瘦身的方向设定及使命拆解供给数据支撑 。
2.1 APK素材解读
图3 APK 架构
•.dex APK 中可能涵盖一个或多个 .dex 资料 ,软件程序内的蓝莓外汇平台怎么开户 Java/ 源码最后会以字节码的方法存在于 .dex 资料中。
•.软件在编译资源会将一些资源或者资源索引打包成.arsc。
•res/ 源码工程中 res 目录下除了 外的资源资料,这些资料路径并且会记录在 .arsc 中。
•lib/ ,当之无愧网即源码工程 jni 目录下的 so 资料,二级目录为 NDK拥护的 ABI。
•/ 与 res/ 资源目录不同,/ 下的资源资料不会在 .arsc 中生成查询条目,且 / 下的资源目录可完全自定义 ,在程序中通过 对象来获取。
•META-INF/该资料夹下主要涵盖 CERT.SF 和 CERT.RSA 签名资料, 以及 .MF 清单资料 。
•.xml 软件清单资料,用于叙述软件基本数据,主要包括软件包名、软件id、软件组件 、所需权限、终端兼容性等。
2.2 SDK大小解读
通过我们自研的能效提高平台[7],可以直观地看到SDK的大小 ,如图4所示:
图4 SDK大小排序(涵盖平台号)
图5 SDK中涵盖的SO库列表及大小
根据SDK解读后结合业务,来判断哪些业务适合做插件化,进而直观的降低包体积 。
2.3 ZIP架构解读
可以用命令输出压缩包中每个资料的具体数据日志,用法 : -l --t --h test.apk >test.txt
输出的日志资料进入如图6所示,每个资料的压缩数据一行 ,包括资料名 、初步大小、压缩后大小等指标:
图6 APK内资料数据大小
对以上日志数据进行逐行解析,根据解混淆后的资料名路径、资料类别进行归类汇总,即可得出Apk的总览数据 ,包括各类别资料的数目 、总大小 、单一资料大小等指标,并设立资料大小索引。
三、瘦身实践
整体实行路径如图7所示 ,主要分为:
1.常规技术计划,XM外汇平台通过插件(代码无侵入、自动化)在编译时期完成APP瘦身;
2.进阶技术计划,将部分业务线差别性的通过插件化或者SO动态获取的方法就行改造 ,业务改造的越多,收入越高;
3.业务优化计划 ,针对业务线的数据埋点 ,生成访问UV进行排名,将UV较低的业务线反馈架构委员会,评估是否可以进行下线或者通过进阶技术计划(2)进行改造,进而减小包体积。
图7 整体实行路径
3-1 常规技术计划 3-1-1 图像应对
经过上述的APP的剖析,得出占用体积第一大的还是图像 ,因此将APP所有含SDK内所有图像在编译打包流程中通过瘦身使命自动完成图像优化应对,整体优化计划如图8所示:
图8 图像优化计划
1.多 DPI 优化:
为了适配各种不同分辨率或者模式的终端,为开发者设计了同一资源多个配置的资源路径,app 通过 获取图像资源时,自动根据终端配置启动适配的资源 ,但这些配置伴随着的难题就是高分辨率的终端涵盖低分辨率的无用图像或者低分辨率的终端涵盖高分辨率的无用图像。
一般现状下 ,针对国内软件市场,App 为了下降包大小,会选用市场占有率最高的一套 dpi( 精选 )兼容所有终端 。而针对海外软件市场的 APP ,大多会通过 打包提交至 Play ,能够享受动态分发 dpi 这一作用,不同分辨率移动设备可以获取不同 dpi 的图像资源,因此我们需要供给多套 dpi 来满足所有终端。在项目中,我们的图像有的只有一套 dpi,有的有多套 dpi ,针对上述两种场景,我们分别在打包时合并资源、复制资源 ,下降了包大小 。
2.转换为webp格式 :
是谷歌供给的一种拥护有损压缩和无损压缩的图像资料格式 ,而且可以供给比JPEG或PNG更好的压缩 。在 4.0(API level 14)中拥护有损的WebP图像 ,在 4.3(API level 18)和更高平台中拥护无损和透明的WebP图像
因此 :我们采用插件在编译时期仅保留针对图像通过供给的shell程序进行格式转换,转换成功删除旧的图像,进而达到APK瘦身的效果
3.png压缩
是一个_好用的png压缩软件一个 ,可以进行有损图像压缩的命令行软件 ,因此在1和2应对终止后,可以利用进行二次压缩,达到更优的图像瘦身 。
3-1-2 R资料内联优化
DEX里是Java/ 源码编译后的字节码资料 ,对DEX的优化其实就是怎么优化字节码资料 ,DEX中涵盖大量的资源索引R资料 ,这里主要讲下如何通过资源ID内联后进行R资料删除,达到APK瘦身的目的:
R资料瘦身的可行性解读
日常开发阶段,在主工程中通过R.xx.xx的方法引用资源 ,经过编译后R类引用对应的常量会被编译进class中 。
();
这种变动叫做内联 ,内联是java的一种机制(如果一个常量被标记为 final ,在java编译的流程中会将常量内联到代码中 ,下降一次变量的内存寻址)。非主工程中 ,R类资源ID以引用的方法编译进class中,不会产生内联 。
(R..);
产生这种状况的原因是AGP打包软件引发的。具体细节,大家可以去查阅一下 在R资料上的应对流程。结论:R类id内联后程序可运行 ,但并非所有的工程都会自动产生内联状况,我们需要通过技术手段在合适的时机将R类id内联到程序中,内联完成后 ,由于不再依赖R类资料 ,则可以将R类资料删除,在软件正常运行的并且,达到包瘦身目的,如图9所示 ,在编译完成后会产生大量的R资料 :
图9 项目R资料生成示意
整体计划如图10所示 :
图10 R资料优化流程
注意事项:在替换阶段一定要加入二次检查 ,防止替换完,运行时出现异常,如下所示:
try {
int value = .(type, name);
}catch ( e){
= " is not found(I),="++",="+owner+"."+name;
throw new ption();
try {
int[] value = .(type, name);
}catch ( e){
= " is not found(I[]),="++",="+owner+"."+name;
throw new ption();
3-1-3 进行资源混淆
1.资源启动流程解读
开发流程中我们通过aapt生成的R.java中的常量来利用资源,而在编译之后利用常量的地方都会被替换为常量的值,如下所示:
final View = .(, , false);
也就是说我们通过利用一个int数值来查找利用资源 。那么是怎么通过int数值找到具体的资源呢 ?我们解压apk可以看到里面有个.arsc资料,这个资料也是由aapt生成,资料中保存着资源id和资源key的映射关系,就是按照这个映射关系找到资源的 。
2..arsc:
图11是.arsc的里存储的映射关系,.arsc可以理解为一个资源映射数据库,根据ID映射其中具体的路径和名称。
图11 .arsc解析
通过解压APK后,将资源资料名进行短链应对比如res//hello.xml转换为r/l/a.xml后 ,然后更改.arsc对应的value值,达到整体的瘦身效果 。
[5]是微信推出资源优化软件,它的基本思想类似于 中的混淆,可以实现以上计划。
3-1-4 7zip压缩
7zip命令说明 :
-t:指定压缩类别 ,拥护7z, xz, split, zip, gzip, bzip2, tar, ....
-m:指定压缩算法 ,默认是
具体流程如下:
第一步:利用7z命令将未签名包解压到指定目录:7za x ${未签名包} -o${7z解压目录}
第二步:首先通过7z命令对解压目录进行全部压缩:7za a -tzip -mx9 ${方向7z资料名} ${7z解压目录}
第三步:获取存储类别资料,通过 SDK中的aapt命令获取压缩方法为的资料列表:aapt l -v ${未签名包}
第四步 :替换存储类别资料,通过7z命令将存储类别资料替换到第二步流程中生成的7zip安装包 :7za a -tzip -mx0 ${方向7z资料名} ${存储类别资料目录}
3-1-5 配置CPU架构
根据不同的CPU架构 ,构建不同的类别的安装包,目前主流终端都是64位机器,因此安卓市场上主要投放的是依据arm64-v8a编译构建的安装包
ndk {
arm64-v8a
3-1-6 arsc 压缩
.arsc 的压缩体积收入很高 ,但对其进行压缩会作用开展速度和内存指标。原因是 :平台在启动 arsc 资料时 ,若 arsc 资料未压缩 ,可利用 mmap 进行内存映射;若 arsc 资料被压缩了,则需要将其解压缩后读取到RAM 缓冲区 ,会提升内存利用,也会拖慢开展速度 。
官方出于同样的思考,从 >=30后不能用这种方法 开展强制要求.arsc ,否则会直接安装失败 ,因此本文不在展开阐述 。
3-1-7 国际化语言应对
京东金融App目前仅在国内市场运营,但是接入的大量SDK中加入了几十种语言一样 ,引发整个体积变大,经过评估可以通过配置 去除无用的语言资源。
{
"zh","en"
3-1-8