微商品牌网手機版 推广

京东APP瘦身:有效减少R文件大小

2023-06-30 02:54:16 來源: 微商网 作者:青鸾传媒

  

微商网消息:

随着业务的发展和版本迭代,客户端项目不断添加新的业务逻辑和新的资源,随之而来的问题就是安装包的体积变大。 前期通过利用无用资源删除各种业务模块,以及大图片压缩或传输到云端、AB实验业务逻辑离线等手段,在减小包大小方面取得了一定的效果。

在瘦身过程中,我们关注了R文件瘦身的概念。 目前京东APP支持插件。 有业务插件项目和宿主项目。 对业务插件包文件进行分析后发现,除了常规资源和代码外,R类文件约占包体积的3%~5%。 分析宿主工程包文件可知,R文件也占3%左右。 经过研究R文件瘦身和业界开源项目的可行性,我们探索出了一套适合插件项目的R文件瘦身技术解决方案。

理论基础—R 文件

R文件就是我们日常工作中经常接触到的R.java文件。 在开发规范中,我们需要将应用程序中使用的资源放入专门命名的资源目录中,并将应用程序资源外部化以单独维护。

_京东插件y_京东x插件

将应用程序资源外部化后,我们就可以使用R类ID来访问项目中的这些资源,并且R类ID是唯一的。

班级 {

@

空白 (@ ) {

极好的。();

(R..);

}

}

在apk打包过程中,通过aapt(Asset Tool)工具打包生成R类文件。 当生成R类文件时,资源文件被编译生成.arsc文件。 .arsc文件相当于一个文件索引表,应用层代码可以通过R类ID访问相应的资源。

R文件瘦身的可行性分析

日常开发阶段,通过R.xx.xx在主工程中引用资源,编译后会将R类引用对应的常量编译到类中。

();

这种变化称为内联,内联是java的一种机制(如果一个常量被标记为final,那么该常量会在java编译时被内联到代码中,减少一次变量的内存寻址)。

在非主项目中,R类资源ID通过引用编译到类中,不会生成内联。

(R..);

京东插件y__京东x插件

造成这种现象的原因是AGP封装工具造成的。 具体可以查看R文件上的处理过程。

结论:R类id内联后程序可以运行,但并不是所有项目都会自动产生内联现象。 我们需要在适当的时候利用技术手段将R class id内嵌到程序中。 如果依赖R类文件,可以在应用程序正常运行的情况下删除R类文件,以达到减小包大小的目的。

插件项目R文件瘦身实践

制定技术方案

目前京东客户端支持插件,整个插件项目包括公共库(一个aar项目,用于存放组件和宿主机共享的类和资源)、业务插件(插件项目是一个独立的项目)项目,编译后的产品可以运行在宿主环境中),宿主(主项目,提供运行环境)。 为了防止插件过程中宿主和插件资源冲突,通过修改插件来保证资源的唯一性。 由于公共资源库和主机被很多业务所依赖,因此变更对这两个项目的影响相对较大。 插件一般由业务模块自己维护,不存在依赖问题。 因此,在业务插件模块实践中首先进行R型瘦身。

对业务插件项目产生的包进行反编译后,发现R类ID没有内联现象,且R类文件有一定大小。 对包中的R文件进行分析后发现,R文件中只包含业务本身的资源。 不包含业务依赖的公共资源R类。

看法 ( , , ) {

this.b = .(R.., , false);

this.h = ()this.b.(R.id.);

this.f = ()this.b.(R.id.);}

结合业界开源项目的研究分析,尝试制定符合京东的技术方案,并优先完成业务插件中R ID的内联以及删除对应的R文件。

1.通过api收集需要处理的class文件

它是一种操作提供的字节码的方式,在类被编译成dex之前,通过一系列的处理来修改.class文件。

@

空白 ( ) , , {

极好的。();

// 通过.()获取输入文件,有两种

// 以源码形式参与编译的目录结构及目录下的文件

// 所有以jar包形式参与编译的jar包

= new (.().size());

= new (.().size());

= .();

对于(输入:){

= 输入。();

为了 ( : ) {

。添加(。());

}

= 输入。();

为了 ( : ) {

。添加(。());

}

}

}

2.结合ASM框架对收集到的.class文件进行分析处理

ASM 是一个用于操作 Java 字节码的类库。 通过ASM,我们可以方便地修改.class文件。

优先识别R类文件,通过访问R.class文件,读取文件中的静态常量,存储临时变量:

@ (int , name, desc, , value) { // 收集R类中final int对应的变量 if (.() && .() &&.() &&.isInt(desc)) { .(, name, value ); } super.(, 名称, 描述, , 值);}

对于非R文件,通过识别代码中的R引用,获取该引用对应的值,并替换id值:

@

void (int, 所有者, 名称, desc) {

如果(==。){

//所有者:包名; name:具体变量名; value:R类变量对应的具体id值

值 = .(所有者, 名称);

如果(值!= null){

//调用该api实现值替换

mv.(值);

;

}

}

super.(, 所有者, 名称, 描述);

}

* 注:以上代码仅为部分原理图代码,非官方插件代码。

在业务模块中引入R型瘦身插件后,业务模块的功能可以正常运行,插件包的体积也不同程度地缩小了3%~5%。

公共资源 R 类 ID 内联

在京东客户端代码中,更多的资源文件集中在公共资源库中,公共库生成的相对R类文件也更大。 分析编译后的apk包内容,公共资源库的R类文件占比高达3%。

公共库与主机一起打包,在主机打包过程中引入了R型瘦身插件。 打包后的apk明显减少。 手机安装apk后,首页正常显示。 异常死机现象,死机类型为Rx not find。 崩溃原因分析如下:业务插件代码使用公共库中的R资源,插件打包过程独立于宿主机打包。 插件打包过程中,只完成了业务模块R类的内联,以及资源R类的内联,基于以上原因,当主机打包过程完成R类的删除和细化时文件中,我们在运行业务插件的过程中自然会报出找不到公共资源R类的问题,导致崩溃。

为了解决这个问题,最初的计划是增加白名单机制,保留业务模块使用的所有公共资源,但这个想法很快就被推翻了。 公共资源的存在本身就是希望各个业务模块能够直接引用这些资源。 而不是自己定义,如果保留的话,肯定有很大一部分资源无法删除,减肥效果也会大打折扣。

由于保留的解决方案不合适,公共资源R类id也被内联到代码中。 前面提到,京东支持插件,整个插件方案是基于aura平台实现的。 我们咨询了aura团队,然后得到了解决方案的新切入点。

aura平台引入了在插件过程中通过aapt2固定公共资源id的能力。 在该能力下,定义的公共资源id将始终是固定的(每个业务插件中引用的公共资源id都是相同的),并且公共资源库中的现有资源不能被其他模块重复定义,否则先前定义的资源将被覆盖。 基于以上结果和规则,我们改进了之前的R文件瘦身功能,将公共资源的R类id内嵌到项目中。

利用appt2的两个参数--ids和--emit-ids实现固化资源id的功能,并将固化后的ids文件命名为.xml,存放到公共资源库中。 业务插件依赖公共资源库。 在此过程中,aura会将.xml文件复制到业务项目临时编译文件夹下的指定位置,并参与业务模块的打包过程。 文件内容的格式如下:

京东插件y__京东x插件

修改R文件瘦身代码,从指定位置读取并识别这部分公共资源,以 的形式存储变量,并在后续流程中替换业务模块中公共资源的id。

地图解析() {

如果(==空){

无效的;

}

ry = ry.();

= .();

doc = .parse(in);

= 文档.();

列表=.();

;

}

}

R资源id代码内联部分如下:

void (int, 所有者, 名称, desc) {

如果(==。){

//先从业务模块R资源中查找

值 = .(所有者, 名称);

如果(值!= null){

mv.(值);

;

}

//从公共R类资源中查找

值=(名称);

如果(值!= null){

mv.(值);

;

}

}

super.(, 所有者, 名称, 描述);

}

方案完善后,结合尚清业务插件进行验证。 上象和宿主机均完成R文件内联细化后,上象模块的业务功能可以正常使用,没有出现异常现象。

考虑到在打包编译阶段引入了R文件的内联瘦身,我们也统计了引入插件后对打包时间的影响。 数据如下:

京东x插件_京东插件y_

结合数据来看,R文件瘦身插件的引入对整体打包时间没有明显影响。

至此,基于京东商城探索的插件工程R文件瘦身开发已经完成。 目前部分业务插件模块已上线验证。 功能上线后,我们也及时进行了崩溃观察以及用户反馈的跟进。 没有例外。 当然,开发者为了减小R文件大小、减小包大小的目的,有多种技术方案。 相关工具参与各个阶段的工作,能够高效、有效地控制包裹体积的增长。 如果您有减肥方面的相关建议和想法,欢迎大家一起讨论。

参考文章:

:

:

APK构建过程:

#建造-

免责声明 ① 本网所刊登文章均来自网络转载;文章观点不代表本网立场,其真实性由作者或稿源方负责 ② 如果您对稿件和图片等有版权及其他争议,请及时与我们联系,我们将核实情况后进行相关删除 ③ 联系邮箱:215858170@qq.com

上一篇: 早餐空腹吃苹果,可以排出“宿便”吗?

發佈評論:
  名字:   驗證碼:

  相关新闻
广告位
闽ICP备15016134号-3   Copyright © 2017-2018   
Copyright © 2017 微商网 www.shixunjie.cn 版权所有 青鸾传媒
统计代码