组件化的一些优点
- 并行开发,冲突减少
- 编译加速,效率加快
- 模块解耦,代码重用
基础功能
就是组件化需要解决的最基本的功能
- 页面传参与跳转,也需要支持
uri
式的链路,包括其中的参数解析,外部唤起等 - 模块之间互相调用,即服务
- 支持拦截器,包括跳转前拦截,跳转中参数替换等
高级功能
- 路由配置可下发,动态性更换,比如某个页面崩溃了,可以下发统一调整去某个页面。
- 支持多对一的路径配置,比如Android与iOS一开始是不一样的,后续某个端可以增加一个新的,有用修改本地代码。
- 支持正则匹配,可以支持任意path直接对接到页面,比如传入一个http链接就可以打开网页,传入一个普通path就打开原生页面
- 支持apt&Gradle插件,通过apt工具生成路由信息,实现对应接口存储路由信息,再通过ASM查找到相关接口的实现类,组合起来,避免手动查找dex的耗时。
- 可能还有各个路由框架自己的特点,比如不止一对一的服务,可以一对多,支持动态增加路由等等
代码划分
组件化,一般是拆的过程,应该怎么拆,拆了之后怎么链接上,是一个值得思考的问题。
我们开发app的时候,基本的代码组成都是:
- 项目业务代码
- 公司内部开发的一些sdk,也叫二方sdk
- 外部的sdk,包括一些开源项目,或者是一些商业sdk。
先引入两个概念:
- 组件:职责单一,无揉杂,可以是单纯业务组件,可以是三方sdk封装的组件
- 模块:混杂但是又带着独立的,可以有多个组件,但是也有自己的独立职责,可以独立运行也可以作为lib被依赖。
我们组件化就是需要把应用拆分成组件与模块,按正常组件化:
- 组件与模块应该各单独一个git仓库
- 模块依赖组件,模块组合形成可运行的应用
- 组件提供本地编译方式与远程依赖方式
本地编译与运行
因为我们模块化之后,为了提高编译速度,也为了方便代码的开发与管理,需要把有需要的模块或者组件进行aar方式的打包,传值远程仓库。
通过devOps的方式,或者是其他的jekines等打包的时候,我们的远程git仓库打包都会使用这些模块的远程依赖。
在本地运行的时候,我们开发那些模块,就把那些模块的本地编译模式打开,那么应该怎么做呢?
这里提供两种方式,但是它们都需要把本地模块添加到setting.gradle
中,添加的方式不是直接添加,而是动态添加,因为每个人需要调试的本地模块不一样,我们就需要利用一下local.properties
这个文件,我们把需要调试的模块以key-value的形式配置在该文件中,然后通过流读取,在之后进行动态配置,例如:
1 | //local.properties文件的配置,它们是对应模块配置的本地路径 |
这就完成了本地模块按需加载,每个人的local.properties
都不一样,需要的就打开就行,之后就需要解决远程与本地的冲突问题,它存在的问题是:
- 假如每次都使用注释或者是一个boolean值,那么灵活性是一般的,我们需要假如本地打开了就使用本地的,没打开就是用远程的
- 假如依赖直接存在传递关系,比如A模块依赖与B,B模块依赖与C,这时候我们需要对B模块进行本地调试,A模块的依赖就需要排出掉B的,否则就会有冲突。
有两种推荐的方式:
- 使用
dependencySubstitution
的方式 - 判断是本地编译的时候,exclude调远程依赖当时
第一种方式:
1 | configurations.all { |
出处可以看:Androd Gradle 使用技巧之模块依赖替换
第二种方式是货拉拉的方式:
1 | /** |
实际使用的时候就是用moduleApi
而不是api
。
二者我会更推荐使用第一种,他不需要配置那么多。