Android 组件化思考
更新日期:
4月份曾在薄荷做过一个关于组件化的演讲,讲解了大众点评Android客户端在组件化方面的实践。
点评方案
随着业务的不断发展,点评Android客户端已经由团购、预订、结婚等多个团队协同开发,当时进行组件化主要有两个原因:
- 解耦隔离,减少彼此之间的影响。
- 提高代码复用性,当业务拓展需要开发新App的时候,可以直接复用之前的底层库。
在Android上,组件化进行模块拆分,首先可以拆分为多Module,但拆分为多Module后,数十个Module跑Gradle的task会对构建速度产生影响,所以我们需要改源码集成为二进制集成,子Module全部打包生成AAR,由一个壳工程去组装构建APK,使用AAR集成后构建速度得到了很大的提升。
为了提高更强的隔离性,各个团队各玩各的,责任明确,我们还把每个Module都拆分成独立的代码仓库。
影响
采用组件化模式进行开发后,对开发也发生了比较大的影响。
- 默认AAR集成,源码调试的时候,需要把代码拉下来,并且修改gradle配置文件,当然这个可以有一套自动化的机制。
- 你需要在合并代码后去发布AAR,如果上下层都有修改,你需要先发布下层的AAR,再发布上层的AAR,有人还可能忘记进行AAR的发布。
- 版本号的升级和同步需要控制,下层版本号修改,上层引用怎么改,自动还是手动?
- 底层库修改了某个方法签名,上层库使用AAR集成,可能编译时不会报错,运行时报错,如果使用全源码编译检查,耗时很长。
- Field超65535,需要编译时修改class文件。
- 如果项目依赖比较复杂,ManifestMerge时间耗时很长,导致AS卡死。
从上面可以看到,组件化在某种程度上降低了开发效率,你很难说组件化利大于弊,我更觉得组件化是件不得已而为之的事情。
冯氏方案
上周MDCC大会上,冯森林做了一场《回归初心,从容器化到组件化》的演讲,讲解了他的组件化方案。
一种轻量的组件化方案,亮点是module在debug模式下作为application,在release模式下作为library,通过共享UID多个module APK运行在同一进程。通过这种方式,各个Module独立运行安装,编译速度也有很大的提升。
反思
看到冯老师的组件化方案,我反思了一下之前在点评的做法。
底层库打包AAR是没有问题的,当然冯氏方案没有提及太多AAR的事情,当项目之间共享底层库的时候,AAR远程依赖是一种不错的方式。
之前为了提高编译速度,我们把上层业务代码(团购、电影等)也打包生成了AAR,这就造成平常开发需要不断发布AAR,尤其是项目灰度后,每次可能是最后一次修改,修改代码后就要发布AAR。
但如果我们采用冯氏方案,上层业务代码就没有打AAR的必要了,可以单库独立编译运行,dex和install时间缩短,只是首次完整编译耗时相对较长,但省去AAR发布的烦恼。同时,单库资源ID不超过65535,不需要编译时修改class文件,省去部分编译时间。单库依赖一般也不会导致ManifestMerge耗时很长。
那如果上层业务代码不打包AAR,怎么集合生成APK呢?要么上层业务代码就不要分库,直接多Module集合在一个项目下,要么拉取源代码修改gradle文件组装项目。第二种集合方式可能不够优雅,需要遵守一些规范,同时完整编译一个项目耗时较长。一般来说,上层业务模块分库的必要性没有那么大,如果分库不那么重要的话,可以考虑第一种方案。