Android 的编译速度一直是业内不断被讨论的话题,2019 年有赞移动沙龙之后,发表了「有赞 Android 编译进阶之路 —— 增量编译提效方案 Savitar 」文章,描述了有赞移动对于编译提效的探索,并提出 Savitar 解决方案。2020 年,这不平凡的一年,Savitar 经过不断打磨,迎来了 Savitar 2.0 版本。
主要流程: 增量加速理论基础源于热修复技术,将本地改动的代码编译生成一个个补丁,然后让 APP 加载补丁,达到加速的目的。在设计和流程方面,相对 1.0 基本不变,只是内部的功能实现得到了加强,并且提升工具整体的稳定性,降低接入难度。
从 2019 年 6月至今,Savitar 累计使用超过 18000 次,平均每天使用超过 30 次,节省了大量的编译时间,下面是 Savitar 部分使用效果统计数据:
项目 | 数据 |
---|---|
成功率 | 92.4% |
平均成功时间 | 13.63s |
平均使用时间 | 13.74s |
累计节省时间* | 535+h |
累计节省时间以零售 Android 工程为统计对象,加速前平均编译安装时间为 120s。
一般的工程,会随着代码量的增加导致工程或模块的编译时间不断增加,但是在使用了增量编译加速之后,可以让工程的增量编译速度不受工程模块代码量规模影响,只与改动量正相关(理论上规模越大的工程,得到的编译提效收益越明显),并且免去安装的过程。在日常的开发中,平均在 15s 内即可完成编译加载运行。
在开发维护方面,得益于动态下发的机制,Savitar 实现了问题快速修复,功能无感更新的能力,维护性更强,体验更好。截止至今,Savitar 的 Runner 已经迭代超过 20 个版本,但插件部分只有几个版本升级。
在早期 1.0 版本的 Savitar 中,是使用引入本地 build.gradle 文件和工程引入加载代码的方式完成集成的,存在较强的入侵性,集成的体验不是很好。在 2.0 中,完成了 Gradle Plugin 完整封装,一键集成,无代码入侵,并且拥有更好的工程通用性,支持任意工程,降低了集成和使用的难度。不仅如此,在 2.0 中还加入了一键化支持、MultiDex 支持、Kotlin internal 关键字支持等功能,完善了支持场景。
由于增量编译需要建立在全量编译基础上的原因,在 1.0 中,需要小伙伴先点击 AS 运行按钮编译一遍,在之后的修改中再使用 Savitar 运行按钮完成编译加速。
在实际使用过程中,很多小伙伴都遇到一个困扰:不知道何时需要点 AS 的运行按钮,何时点 Savitar 的运行按钮。为了解决这个选择困扰,Savitar AS 插件实现了构建一键化支持:无需使用原有 AS 运行按钮,只点击 Savitar 运行按钮就行。Savitar 会根据本地构建配置自动识别是否可以进行加速编译,如果不行,就自动执行现有 AS 运行配置(支持 Flavor 切换),达到无缝切换。
此处的 multi-dex 问题并不是我们在 Android 开发过程中处理的 multi-dex 问题,是指 dx 工具把 .class 转 .dex 的流程,存在单个 dex 引用数量不能超过 64K 的限制。超出限制会导致编译失败。
这个问题常常出现在修改资源之后,因为工程本身模块较多,R 文件引用数量过多导致在修改资源之后编译 R 文件会出现:
trouble writing output: Too many field references to fit in one dex file: 86151; max is 65536.
dx 工具是支持 multi-dex 编译的,只需要在参数里面填入相关的参数即可:-
dx ... --min-sdk-version=xx --multi-dex --main-dex-list={path_to_main_dex_list.txt}
在以上参数中,关键参数是 path_to_main_dex_list.txt
,用于自定那些 class 需要加入 classes.dex 中。Gradle 针对 minSdkVersion < 5.0 的应用,会在编译时在 app 的 build 目录下面生成一份 mainDexList.txt 文件,可以直接将此文件作为参数传递。但是在 5.0 或以上不会生成这份文件,并且在 5.0 以下但是当前连接调试设备系统大于 5.0 时也是不会生成的。
经过分析,其实在 5.0 以上的情况 dx 执行过程我们并不需要工程里面的 mainDexList.txt,只需要一个空白的 mainDexList.txt 即可。原因是 Savitar 的产物是用于动态加载的,并不需要像生成 APK 那样关心系统对于 multi-dex 的支持问题。
在 kotlin 中,用 internal 访问修饰符声明的包、类、成员变量或者函数可以在 同模块
内任何地方访问到,这对于 SDK 的封装非常有用。关于 模块
这个概念,官方的解释如下:-
1 一个模块是编译在一起的一套 Kotlin 文件,例如:
2 一个 IntelliJ IDEA 模块;
3 一个 Maven 项目;
4 一个 Gradle 源集(例外是 test 源集可以访问 main 的 internal 声明);
5 一次 <kotlinc> Ant 任务执行所编译的一套文件。
简单的讲就是:使用 kotlinc 在一次编译中所有的文件的集合。因为每次 kotlinc 编译文件之后都会生成一个 xxx.module 的文件,这个文件会记录本次编译所有的类的信息,在编译 internal 修饰的方法时,会进行可见性检查。举一个例子:A、B 两个类使用 kotlinc 一起编译后,两个算是一个模块,但是如果 kotlinc 分别两个文件编译就不算一个模块。在增量编译中,如果修改文件里面存在对于 internal 修饰的代码调用时,就会出现:
1 // B 中方法 A 的 internal 方法 sayHello()
2 error: cannot access 'sayHello': it is internal in 'A'
这个问题在官方文档和 kotlinc 自带的 help doc 中没有说明如何解决,在研究了 kotlin 的源代码之后,发现存在一个friend_paths参数,内容是:
1 value = "-Xfriend-paths"
2 valueDescription = "<path>"
3 description = "Paths to output directories for friend modules (whose internals should be visible)"
通过使用这个参数,可以为正在编译的文件扩展 internal 可访问区域,解决增量编译中由于单独编译导致的 internal 访问问题。
在 1.0 的版本中,主要目的是尽快解决困扰已久的编译耗时问题,大幅度提升日常开发编译速度。开发时也是主要覆盖了一些核心的开发场景,针对一些特定场景的问题没有投入太多时间解决,因此遗留了一些问题待解决。
为了达到极致的编译速度,Savitar 只会编译修改的文件,这样的策略可以尽可能多的减少编译量,但是会带来一个正确性问题:类之间可能是存在依赖关系的,如果修改了类公开的 API (方法,变量,常量,类等)但是没有编译依赖方,可能会导致运行时崩溃。例如:
1 // 原始函数
2 public void sayHello()
3 // 修改后函数
4 public String sayHello()
返回值从 void
变为 String
并不会导致编译错误,但是在运行时会导致 NoSuchMethodException
异常。如果能再次编译依赖方,加入到最终产物中就可以避免这样的错误。
解决这个问题有两个关键点:文件改动分析与改动文件的直接依赖方定位。文件改动分析是指文件的改动是否需要检查依赖方,例如方法内部实现改动是不需要的,公开常量修改时需要。精确的分析结果是保证最小编译量的前提。
改动文件的依赖方定位只针对直接依赖形式,不需要分析间接依赖的情况。对直接依赖方编译会有两个结果:编译成功或者失败。这样也可以将一些编译错误问题提前暴露。
我们可以通过 ASM 技术进行字节码分析,在全量编译阶段对工程内源文件生成的 class 进行解析,记录所有 class 的信息,存储到文件中。
1 public class ClassInfo {
2 public int access;
3 public String name;
4 public String superName;
5 public Set<String> interfaces;
6 public Set<String> importClass;
7 public List<Fields> fields;
8 public List<Methods> methods;
9 // ...
10 }
在完成改动文件编译后,生成改动类的 ClassInfo
,再比较新旧类信息的每个字段,得出需要编译的依赖方,最后再进行依赖方编译即可。
1 /**
2 * src - 原始类信息
3 * changed - 修改类信息
4 * deleted - 删除类文件
5 */
6 Set<String> analyzerChange(src, changed, deleted)
对于修改为删除的文件需要注意的一点是需要删除对应原工程里面生成 .class 文件,否则会导致不能检查到编译失败的问题。
在「QQ音乐Android编译提速之路」也针对这个问题进行的分析和提供解决方案思路,解法大同小异。
此前已经将 Savitar 的 AS Plugin 发布到了 Jetbrains 的插件仓库中,但是并未将 Runner 开放,因为使用问题收到了很多热心小伙伴的邮件反(tu)馈(cao),很多小伙伴都表示对 Savitar 的期待和希望可以早日用上,在此先感谢各位热心小伙伴的关心,开源的计划已经在准备中,不过在此之前,稳定性和更多场景适配仍然是主要内容,下面是一些规划:- 实现 CLI 接入,可以应用到跨平台技术开发过程
Savitar 从一个想法到现在的 2.0 版本,离不开每一个小伙伴的投入。对于每个成员来说也是一次学习的过程。目前 Savitar 已经在零售和微商城团队中应用,未来会应用在更多团队中,在实际的业务中不断磨练、完善,最终完成社区开源计划。我们对于开发效率提升的追求永不停止,感谢大家的关注。
本文由哈喽比特于3年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/KTlC2CTCuwwEYKQ7uql-rA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。