墨迹天气用户多:
墨迹月活跃用户过2亿8千万(数据来源:艾瑞)

墨迹天气功能多:

墨迹天气Android端版本多:

用户多,功能多,版本多带来了前所未有的挑战
-
稳定性要求高
-
需要方便团队分工
-
需要灵活的功能添加与裁剪能力
看我们如何一步步优化架构,满足业务需求
早期架构:多进程架构:
最初没有架构,代码开发式增长。随着业务的快速发展,代码、内存、安装包大小都在增长,对系统资源的占用也越来越多。墨迹开始转向多进程架构,独立的通信进程保证推送效率,独立桌面插件进程保证插件更新等。

多进程架构解决了程序运行时资源占用和稳定性问题,对于代码管理并没有做出改进。
中期架构:多进程基础下模块化架构
时间继续推进,随着项目扩大、人员增多、分工合作,多人合作开发同一项目面临挑战,同时新增的手机厂商预装项目对天气提出了更多个性化定制需求。分离核心功能和其他业务模块变得越发重要。为此,再次进行架构改造,把各种产品功能拆分到相互独立的模块中。使用模块化拆分后,一定程度上解决了分工合作带来的挑战,并保留了功能重组的可能性。

模块化架构的不足:
业务逻辑不断增加,模块越来越多,模块间互相依赖愈发严重,模块间依赖关系难以理清,功能增加和裁剪都无从下手。所有模块都打包到一个项目里,缺少了编译上的隔离,模块间的代码边界也出现一些劣化,经常出现一个功能改动影响了其他模块代码造成的bug。

问题的原因:
在之前的架构中,大量使用Event事件总线作为模块间通信的方式,也基本是唯一的方式。使用Event作为通信的媒介,就需要统一定义Event,使模块间都能知道Event的结构。模块间就出现了各种依赖关系,产生严重耦合。同时Event不能跨进程工作,跨进程数据交换费时费力容易出错,成了项目顽疾。在新架构中迫切需要使用新的通信方式来完成模块解耦,并且要能方便完成跨进程交互。

解决问题:
知道了问题所在,就需要针对性的解决,提出了组件化架构
新的组件化架构有三个目标:
-
改变通信方式
-
重新设计模块
-
约束代码边界
改变通信方式:
将Event事件总线升级为使用APIManager的ServiceManager方式。使用服务注册的方式,类似于C/S架构,只暴露接口不暴露实现。业务逻辑间的依赖减少,同时通信方式还封装了跨进程调用实现,服务使用方和提供方都无需关心是否跨进程,简化开发。


重新设计模块:
所有模块编译到一个项目中出现了大量耦合,同时也不利于功能增加与裁剪。需要一种灵活的模块设计保证组件解耦的同时,各个组件可以正常引用与初始化。将原来的模块按照功能形成组件,并定义了组件的生命周期,由组件生命周期完成组件的加载与初始化。使得组件有了单独运行调试的能力,提高了开发效率。
约束代码边界:
模块间可以直接引用造成了诸多问题,需要编译隔离的同时方便打包与裁剪。

优化后架构:组件化架构

通信方式使用APIManager,APIManager内部封装了跨进程调用,服务方提供服务,客户方查询并使用服务,简化通信,提高开发效率。
模块间使用APIManager通信,只依赖接口,不依赖实现,消除了模块间耦合。方便实现功能添加与裁剪。
组件之间互相没有依赖关系,而是所有组件统一依赖于公开的服务,编写代码过程中无法引用到服务的具体实现,也就保证了所有调用都严格准守定义好的服务接口,保证了组件间代码隔离,强化了代码边界,更利于团队分工合作。
组件生命周期:
组件提供的服务都需要先在APIManager中注册才能使用,产生了新问题:
-
怎么注册组件中的服务
-
组件间相互没有引用的情况下,如何保证服务能正常调用
因此引入组件的生命周期,在组件的生命周期中调用组件中服务的注册与反注册,通过组件生命周期就可以保证组件正常提供服务。
组件生命周期可以简化为组件加载和组件卸载。

什么时候调用加载和卸载呢?
组件需要支持打包过程中灵活的插入和裁剪,就不能通过硬编码的方式调用生命周期。通过Gradle编译系统插件,在编译过程中动态扫描打包的组件,并自动插入对组件生命周期的调用,完成了灵活的组件配置与完整的组件生命周期。

编译速度优化:
编译过程中插入了对组件的扫描和插入组件生命周期代码等额外工作,造成了编译速度下降。使用编译缓存和增量编译技术后,单次编译增加的编译时间由30秒降至7秒,提高了开发效率。
模单独运行:
利用灵活的模块裁剪能力,可以在开发过程中单独运行一个模块。
例如在开发Module A的过程中,只将Module A,以及Module A依赖的 Module F、Library A 和其他基础组件一起打包运行,极大减少了编译运行时间,提高了开发效率。
使用了新的组件化架构后,组件间降低耦合,增加了功能定制灵活性,各业务线能最大程度共享代码。约束了代码边界,减少了部门间分工合作造成的Bug,提升了稳定性。组件模块单独运行,减少了开发过程中编译等待时间,提高了开发效率。
本文作者介绍:
作者简介 段迪 墨迹风云科技股份有限公司高级Android工程师,专注于Android移动端性能优化、应用架构。
