写点什么

初探 Android 组件化,四个步骤把握组件化核心要领

用户头像
Android架构
关注
发布于: 57 分钟前

2.1 有赞微商城 Android 组件化

有赞微商城分享的组件化方案详细介绍了实施组件化方案的背景,在基于日益复杂的业务模块中,代码出现大量冗余、打包时间逐渐增长以及各个业务模块之间相互耦合等。面临的问题有:


  • 模块只是项目结构的概念(一个模块一个 Module),在逻辑层并没有模块这个概念

  • 模块本身没有生命周期控制

  • 公用服务中心化,公用逻辑部分全部都在 Common 模块中

  • 模块对外暴露的服务不可知,都是直接依赖模块内部的代码逻辑

  • 模块无法单独打包,针对模块的代码改动,只能全量打包之后才能看到效果


这些问题也是很多项目发展到一定阶段要面对的问题,为了解决这种问题,就需要对架构进行调整重构,严格按照组件化的强要求来进行业务模块的拆分。下面我们看下有赞团队是如何去落地组件化方案。

1. 模块的拆分与抽象

将模块的功能抽象出基础类,形成模块化支持组件,这个基础 Module 提供的功能有:


  • 抽象出模块本身作为某一类业务的容器,即所有业务模块需要实现自己的模块类,继承自我们的 BaseModule,并在 App 壳工程中进行注册;

  • 模块对象跟 Activity 一样,拥有生命周期的概念,需要在生命周期的不同阶段处理自己相应的逻辑(注册服务、初始化数据等);

  • 模块可以注册的对外暴露的服务的实现,在注册模块的时候,模块携带的服务也会被注册到 App 的服务中心。

2. 公共业务去中心化

这里的公共业务是指在 App 中抽取的 Common 模块,这个模块随着项目复杂度的提升,像一个大储物柜,每个人都往里面塞了很多业务代码,造成了该模块代码冗余增多以及维护难度增大。解决思路是:


  • 将公用的业务模块向上抽离到业务模块中(所谓业务模块的服务化);

  • 将基础组件抽象到一个独立的组件中;

  • 将一些基础类下沉到不包含业务逻辑的底层核心库中。

3. 业务模块服务化

简单来说,就是根据业务划分为多个模块,模块之间的交互以互相提供服务的方式来完成。常见的基本方式有:


  • A 模块直接依赖 B 模块,直接调用 B 模块的代码逻辑;

  • AB 模块中的公用部分放到 Common 模块中,通过调用 Common 模块的代码实现依赖;


在有赞的组件化中,提出了通过 API 的方式实现,每个模块通过 API 暴露内部的数据和服务,以此来完成通信。常见的 API 实现方式有:


  • 协议,类似于 app://order/detail/get?id=100,通过 JSON 传递数据,但是面临的问题维护成本高,服务修改导致引用方无感知;

  • 接口,通过暴露的接口完成数据的交互,引用方需要依赖该模块,依赖和发布成本高;


这里有赞团队选择通过接口的方式实现,这种方式的稳定性和版本控制做的更好,对于改动来说,编译过程自动会帮你校验改动的影响面,而引入依赖和发布成本高的问题,完全可以交给构建工具(Gradle Plugin)来解决。


业务实现层需要做的,就是实现自己模块本身的业务逻辑,并实现自己提供的 API 接口,暴露对外的服务。

4. 基础组件抽象

很多的基础组件都是统一在 Common 里面进行封装的,例如:账号库、网络库、图片加载等等,导致该模块臃肿。针对这种情况,需要针对该模块进行重构:


  • 将常用的基础组件整理,抽象成单独的一个抽象层,里面定义了一系列基础组件接口(图片加载、Web 容器、JsBridge 调用、账号等等);

  • 把统一实现的组件放到另一个依赖里面,可以在 App 中进行具体实现的注册,而业务模块本身,可以只依赖抽象。

5. 单/多模块打包

这部分是通过自定义 Gradle Plugin 实现 Module 的类型,在开发阶段是 Application 类型,可以单独运行调试,在发布阶段是 Library 形式。


新的架构图:


2.2 知乎 Android 客户端组件化实践

知乎 Android 客户端组件化实践一文中,介绍到随着项目团队的不断扩大,同样是面临代码耦合的问题以及现有架构在开发过程中研发人员协作方面也显得越来越力不从心。下面我们看下知乎团队如何落地实践组件化。

1. 解耦业务模块

组件化第一步就是要解耦冗余的业务逻辑,这里主要包含:


公有代码处理


基础的业务逻辑拆分出独立的业务组件,将 Common 模块进行降级处理,严格限制大小增长。


初始化


有些组件有在应用启动时初始化服务的需求时,通过自定义生命周期框架进行实现初始化任务依赖和先后顺序的管理。


路由


界面间使用 Url 进行跳转,内部实现了一套灵活小巧的路由框架 ZRouter 完成路由跳转功能。


接口


不同业务之间不可避免的会有一些调用,为了避免组件的直接通信,通常都是使用接口依赖的方式。实现了一个 Interface Provider 来支持接口通信,它可以通过运行时在动态注册一个接口,同时也实现了对于 ServiceLoader 的支持。


组件 API 模块


为每个有对外暴露需求的组件添加一个 API 模块,API 模块中只包含对外暴露的 Model 和组件通信用的 InterfaceEvent。有需要引用这些类的组件只要依赖 API 即可。比如:


  • template :组件代码,它包含了这个组件所有业务代码;

  • template-api:组件的接口模块,专门用于与其他组件通信,只包含 ModelInterfaceEvent,不存在任何业务和逻辑代码。

2. 组件工程半自动拆分

解耦拆组件是一个很头疼的问题,如果依赖关系比较复杂,很容易出现到处编译错误,只能靠人肉一点点挪了。为了解决这个问题,知乎开发了一个辅助工具 RefactorMan: 它可以递归的解析出工程中所有源码的引用和被引用情况


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


,同时会根据预设规则自动分析出所有不合理的依赖,在开发人员根据提示解决了不合理依赖之后,即可将组件一键移出,大大减少了拆组件的工作量。

3. 联合编译完整包

通过 sourceSet 整合资源的目录,编译时使用 sourceSet 依赖,其他时候使用 module 依赖,保证各个子业务可以独立运行,对外发布只有一个组件。


新的架构图:



它包含 4 个层次:


  • 主工程:除了一些全局配置和主 Activity 之外,不包含任何业务代码。

  • 业务组件:最上层的业务,每个组件表示一条完整的业务线,彼此之间互相独立。

  • 基础组件:支撑上层业务组件运行的基础业务服务。

  • 基础 SDK:完全业务无关的基础代码。

2.3 爱奇艺知识移动端组件化探索和实践

组件化对于任何一个业务场景复杂的 App 来说都是一个必经的过程,随着公司的业务线拆分发展,必然会出现同样的业务模块出现多端多套代码的情况,造成很大的维护成本。在实施组件化之前,先明确组件化需要解决的业务问题,而不是为了组件化而组件化。


在爱奇艺知识移动端实施组件化时,组件化的目标定义为以下几个:


  • 解决多端代码维护问题


根据业务特点,横向和纵向划分组件,以组件为单位承接迭代需求,各端进行组件复用。


  • 解决跨组件调用和组件间路由的问题


业务划分更加清晰、组件间解耦更加彻底、组件间通信更高效,对原有业务模块进行抽离和整合,明确组件间的业务边界。


  • 提升开发效率,方便开发调试


组件可以单独编译和调试,使模块开发者更聚焦本模块业务。


  • 提升集成和提测效率


各端项目需要哪个组件,可以直接通过工具快速集成和提测。


基于以上四个目标,结合自己的业务需求,新的架构分为基础组件、功能组件和业务组件



其次是关于组件化实践中比较核心的两个技术点实践:组件间交互和组件间路由。


组件间交互


组件间交互的难点是降低组件耦合度,最好能达到完全无侵入式的调用。在 Android 端,组件间交互使用的是 ZRouter 组件,每个组件对外提供一个服务接口 service,接口的实现交给对应组件内。在组件初始化注册时候,会同时注册该 service 接口和对应 service 实现。业务方使用时,只需要通过 service 接口调用组件功能。这样组件间就没有了直接依赖关系,实现了组件间解耦隔离。


组件间路由


组件间路由跳转方面,用了注册 URL 的方式,注册的时机分为静态、动态和懒加载三种,懒加载方式即为在调用跳转方法时检查 URLClassName 是否已经注册绑定,如果未绑定则从模块静态信息表中获取并完成注册绑定。这里爱奇艺团队借鉴业内优秀的组件化思想,专门开发了一个用于组件间 UI 跳转的 UIRouter

3. 实现组件化

3.1 四大步骤实现组件化

通过上面一些优秀案例的分析,当一个组织进行架构重构和调整时,基本上是积重难返、严重影响开发效率。所以需要对架构进行重构,提升开发效率。结合以上案例,总结出四大步骤来辅助我们实现一个组件化架构的设计。

1. 明确组件化的目的

任何架构的重构或调整,都是为了解决特定的问题,在实施组件化之前,一定要明确此次架构重构需要解决的问题,以便能够有的放矢,而不是为了组件化而组件化。

2. 业务拆分

组件化有一个重要的目的是为了降低代码之间的耦合,所以需要根据自己的业务进行拆分。在业务拆分的过程中一般涉及到公共代码的处理、业务模块的拆分。

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
初探 Android 组件化,四个步骤把握组件化核心要领