有赞Android秒级编译优化实践
如果无法正常显示,请先停止浏览器的去广告插件。
1. 有赞Android秒级编译优化实践
有赞-明天
2. ⽬目录
背景
⽅方案调研
有赞⽅方案
实践成果
未来规划
3. 背景
Android端现状
Kotlin
33%
客户端
Phone
Pad
每周发版
业务
账户
交易易
商品
45W
库存
共26个⼦子业务模块
导购
…
⽉月均上线功能 50+
Java
67%
4. 遇到的问题
编译时间
18
18
团队开发效率下降
15
13.5
12
新⼈人⼊入⻔门成本提⾼高
9
8
不不利利于紧急问题修复
4.5
0
2016
编译时间⻓长,开发体验差
2017
2018
2019
必须要解决编译慢的问题
5. ⽅方案调研
框架 优点 不不⾜足
BUCK 强⼤大的编译体系 配置复杂,部分特性不不⽀支持
Freeline 极致的部署速度 语⾔言只⽀支持Java
InstantRun 兼容性最好 部分场景不不适⽤用,加速不不明显
6. 需要⼀一个适合有赞的⽅方案
7. 场景分析
A同学需要对某个模块进⾏行行需求开发
全量量编译运⾏行行
增量量编译运⾏行行
开发完成
8. 场景分析
过程 耗时问题点 优化点
全量量编译 所有模块都是源码编译 ⽆无关模块⼆二进制集成
增量量编译 修改部分⽂文件需编译整个模块 修改⽂文件单独编译
安装运⾏行行 Android版本,机器器之间差别⼤大 利利⽤用热修复去除安装时间
9. 优化⽅方向
基于热修复与部分编译增量量加速⽅方案 基于模块⼆二进制化全量量加速⽅方案
• 如何实现修改识别?
•
如何⽀支持源代码/⼆二进制⽆无缝切换?
• 如何⽀支持代码、资源⽂文件编译?
•
如何降低⼆二进制发布操作成本?
• 如何⽆无缝对接热修复?
•
如何管理理⼆二进制版本?
• 如何降低使⽤用成本? •
如何实现发布流程⾃自动化?
10. 增量量加速⽅方案
Savitar
11. Savitar
Savitar能够有效减少模块修改编译时间,配套IDE插件,使⽤用⽅方便便。
主要特点
• ⽀支持主流开发语⾔言(Java & Kotlin)
• 集成、使⽤用简单
• ⽀支持调试
• ⽀支持多分⽀支管理理
12. Features
代码 Java、kotlin
资源 layout、values、assets、images
扩展 kotlinx
操作 GUI界⾯面
其他 调试、多分⽀支管理理(基于GIT)
13. GUI插件
版本更更新器器
任务执⾏行行器器
脚本执⾏行行器器
可运⾏行行Jar
配置检查器器
⽂文件分析器器
⼯工程⽀支持
补丁加载器器
Gradle插件
脚本⽣生成器器
外部依赖
Javac
Watchman
Git
14. 运⾏行行流程
获取改动信息
改动代码
改动资源
获取⼯工程信息 ⽣生成编译产物 依赖信息 Java编译 dex加载
⽬目录信息 kotlin编译 资源加载
GIT信息 资源编译
dex⽣生成
apk⽣生成
重启加载产物
15. 改动获取
改动检测
Watchman + Git:基于 watchman 实现⽂文件修改监控,并且增加对于 GIT 提交记录。
多 Flavor ⽀支持:提前获取⼯工程每个 Flavor 的 source set,过滤掉⾮非当前 Flavor 的代码。
避免分⽀支切换导致识别到有⼤大量量⽂文件修改
上次构建成功Git
提交ID
Git Diff⽂文件集合
Flavor过滤
修改⽂文件集合
本地未提交修改
Watchman Diff⽂文
件集合
结果修改集合
16. ⽂文件改动限制
⼤大量量⽂文件修改的情况
GitLab
⼤大量量⽂文件改动影响
pull
本地⽂文件
其他分⽀支
merge
•
•
•
•
存在不不⽀支持的修改
本地产物可靠性变差
检测成本⾼高,出现频率低
增量量效果不不明显
解决策略略
•
•
⽬目前限制最⼤大⽀支持50个⽂文件
超过最⼤大限制⾛走原有Gradle流程
17. 资源⽀支持
资源ID固定
aaptOptions
generateResValues
generateResources
checkManifest
processManifest
mergeResources
—emit-ids
资
源
处
理理
流
程
实现资源 ID 固定和记录,保证后期对于资源的修改
时不不会出现错乱
18. 资源⽀支持
资源的编译
对于⾮非 values 资源,基于 AAPT2 的 link 模式,将资源编译后的 flat ⽂文件替换之前的 flat ⽂文件,在
使⽤用 link 命令完成打包即可。
对于 values 资源,因为之前全量量编译的产物是已经合并过的,所以不不能使⽤用单个修改 flat 替换合
并过的 flat,对于这种场景⽬目前是采⽤用重新执⾏行行⼀一次处理理资源的 gradle task。
⾮非values资源
AAPT Compile
.flat⽂文件替换
gradle merge
values资源
merged资源
AAPT Link
资源Apk⽂文件
19. 源代码⽀支持
源代码编译
借助 javac 与 kotlinc 实现对单个⽂文件的编译,所有的编译依赖会在运⾏行行时收集,根据本次的改动
会⽣生成不不同的编译脚本,保证每次编译的正确性和速度。
关于 Java 与 Kotlin 混编
先 Kotlin 后 Java 原则
Java class
Kotlin 编译 Java 编译
dex
class
20. Kotlinx ⽀支持
kotlin-android-extensions
⽀支持我们在代码⾥里里⾯面直接⽤用
控件的ID即可获取到实例例并
操作调⽤用,但是这并不不是
标准的kotlin语法
21. Demo
22. clean build怎么办?
23. 全量量加速⽅方案
EnjoyDependence
24. EnjoyDependence
EnjoyDependence是集依赖管理理、构建发布⼀一体的 Android 模块⼆二进制化⽅方
灵活的发
布⽅方式
易易⽤用的依
赖管理理
EnjoyDependence
接⼊入成本
低
25. Features
模块依赖管理理 构建发布管理理
• ⽀支持每个模块源代码/⼆二进制⽆无缝切换
• ⽀支持多 Flavor 发布
• ⽀支持模块卸载
• ⽀支持 CLI 命令参数执⾏行行
• 配套 GUI 插件与扩展配置
• ⽀支持增量量/全量量发布
• ⽀支持⾃自定义⼆二进制版本 • ⽀支持扩展配置
26. GUI
更更新器器
ARR/code 配置
发布服务
Gitlab
MBD
构建发布
发布脚本
依赖管理理
发布配置 依赖配置 配置扩展
发布插件 依赖管理理插件 核⼼心插件
Maven插件 com.android.library 基础依赖
27. 模块依赖管理理
Code/AAR 切换⽆无缝
依赖配置
需要替换的模块
依赖替换
配置的AAR版本
28. 模块依赖管理理
AAR版本配置
卸载配置
AAR配置项
29. 构建发布管理理
发布流程
发布模块确定
发布依赖确定
编译打包
Maven发布
版本回写
实现基线版本⾃自动修改
30. 增量量发布策略略实现
基于 GIT 提交记录上次发布节点,利利⽤用 DIFF 获取修改模块,实现发布内容确定。
源码依赖配置去除
模块之间存在源码依赖,在创建 POM ⽂文件时会⽣生成⽆无效依赖,如果不不加过滤处理理,会导致后期依
赖 AAR 时出现部分依赖找不不到的错误。
业务模块A
基础模块
31. 构建发布管理理
重写发布依赖获取⽅方法排除⾮非法依赖
filterDependency⽀支持配置
32. 构建发布管理理
发布⽅方式⽀支持
Merge Request
⾃自动发布
开发分⽀支
发布分⽀支
CI检查
⼿手动发布
发布流程
33. 全AAR编译 Demo
34. 实践成果
35. Savitar
优化前
110
优化后
110
Q3季度累计使⽤用超过 6800 次,累计节省编
译时间超过 180 个⼩小时。
82.5
55
27.5
0
增量量编译提速 8 倍
15
平均增量量编译时间(秒)
36. EnjoyDependence
优化前
AAR单模块开发
AAR APP
16
15
12
全量量编译速度提升 3 倍
8
4
0
4
平均编译时间(分)
3
37. 未来规划
Savitar
•
•
•
•
EnjoyDependence
动态⽣生成代码⽀支持
SO⽀支持
完善对⼀一般⼯工程适配
开源
•
•
完善对⼀一般⼯工程适配
开源
38. One More Thing
39. iOS 全量量加速⽅方案
EnjoyPod
40. Features
个性化配置,⽆无 Git 侵⼊入
发布流程⾃自动化
本地配置,⽆无需担⼼心污染远程代码
代码提交⾃自动触发⼆二进制打包
Pod⿊黑⽩白名单,源码/⼆二进制⾃自由切换 产物内⽹网存储,下载快速
⽀支持业务模块⼆二进制化
⼀一键完成项⽬目结构适配
⽀支持插件⾃自动更更新
Pod插件更更新⾃自动化,减少通知成本
41. EnjoyPod
Goods.xcodeproj
Stock.xcodeproj
Home.xcodeproj
⼯工程Git
⼆二进制Repo
FTP
服务层
Trade.xcodeproj
Jenkins部署的Packager
AFNetworking SDWebImage Masonry
RetailGoods RetailHome RetailStock
配置⽂文件-开启三⽅方/业务⼆二进制 相应⽩白名单
配置层
Pod插件-读取配置,修改依赖,指向⼆二进制源
Retail.xcworkspace
42. 成果
源码build
10
开启Pod⼆二进制
源码fullbuild
开启业务⼆二进制(保留留1个源码⼦子⼯工程)
30
10
28
7.5 22.5
5 15
3
2.5
0
CI平均编译时间(分)
7.5
0
3
⼯工程平均编译时间(分)
43. 谢谢~
Q&A