干货---从智行-Android-项目看组件化架构实践

以上大的目标点主要是来解决之前遇到的问题,也是项目架构调整的首要目的。

2.2 组件化架构调整的整体规划

2.2.1 基础组件的拆分

智行 Android 项目的基础组件主要分为业务基础组件和功能基础组件,其中业务基础组件包含登录组件、自定义 View 组件、项目网络层组件等,这些和业务有关联,提供给各业务模块的基础组件,根据具体情况拆分成 aar 或者 library,像登录,基础网络层这样较为稳定的组件,一般直接打包成 aar,减少编译耗时。而像自定义 View 组件,由于随着版本迭代会有较多变化,就直接以源码形式抽离成 Library。

基础组件的调整相对较为简单,主要就是按照功能或者业务拆分成 Library ,处理好之前的引用的地方即可,但是对于拆分出来的 Library 的质量和后续维护工作是要求相对较高的,作为基础的组件,是需要为各业务模块提供基础的功能的,重要性是相对较高的。

基础组件库的编译版本设置一般是和主工程同步的,为了方便后续升级和维护配置,可以使用如下的方式来实现 library 使用同一份配置:

ext.libDefaultConfig = {
minSdkVersion 19
targetSdkVersion 25
javaCompileOptions {
annotationProcessorOptions {
includeCompileClasspath = true
}
}
}

定义一个通用的 DefaultConfig 配置,设置统一的 SDK 版本信息和编译选项,在 Library 的 build.gralde 文件中使用如下方式即可应用到配置:

android {

defaultConfig libDefaultConfig
}

这样既可以保证基础组件库的编译配置统一,也方便后期统一修改和升级。

对于再基础点的组件,例如 Support Library、json 库等,绝大多数基础组件都会使用到。为了避免每个独立基础组件都去引入对应的依赖,还要尽可能得保证版本的统一,我们使用了一个空壳 Library 来一次性引入这些基础的依赖组件。

这个 Library 叫做 BaseDependencies,然后其他的基础组件去依赖 BaseDependencies,这样就可以保证基础组件对这些基础的依赖版本做到一致,后续的升级改动位置也相对较为集中。如此调整后的依赖如下图所示:

当然这样的也有一定的弊端,就是每个基础组件都可能存在引入冗余的依赖,对于后续可能需要提供给第三方的基础组件,还需要进行改动才可以独立出来。

2.2.2 业务模块的拆分和配置

业务模块的调整是组件化中最重要的,这里的模块也是组件,对于这类组件的调整目标就是做到能够独立运行。业务模块的调整主要分两步:

1)业务模块的拆分独立
2)业务模块的配置

由于之前各业务的代码以不同包名来进行区分,各业务代码也是比较集中的,拆分出来还是相对较为容易的。遇到两个业务模块都会使用到的类的话,就将对应的类下沉到 Base Module,当然这种情况也是尽可能去避免,否则 Base Module 会越来越臃肿,如果不加以控制,那么业务模块就变成了一个空壳,失去了组件化原本的意义。

拆分成独立模块业务,彼此之间是平级的关系,无依赖关系,从而从结构层面达成了分离的目的,避免了之前一不小心就出现的类相互引用,耦合严重的问题。

业务模块拆分成独立的 Library 以后,就是对其进行配置,这也是组件化的关键步骤,既要使得各个业务模块可以独立运行,又要保证各个模块作为整体 App 的一部分,关键就在于不同场景下给每个业务模块应用不同的插件类型。

独立运行时,需要使用:

apply plugin: ‘com.android.application’

而分独立运行时,则需要使用:

apply plugin: ‘com.android.library’

为了方便业务模块的在这两种模式下的快速切换和统一调整,我们使用了以下的设置方式:

// 项目的 build.gradle 中配置模块是否独立运行
def isSingleCompile = false
ext.isSingleCompile = isSingleCompile

if (isSingleCompile) {
ext.COMPLIEMODE = ‘com.android.application’
} else {
ext.COMPLIEMODE = ‘com.android.library’
}

// 业务模块的 build.gradle 中应用

这样在切换时,只需要修改 isSingleCompile 的值,就可以在独立运行和作为模块运行之间切换。

当业务模块独立运行时,还需要配置独立的 Application 和启动页,以及一些特殊的资源文件,这里同样是根据 isSingleCompile 的值来配置 sourceSets 中的属性:

sourceSets {
main {
manifest.srcFile MANIFEST_FILE
res.srcDirs = RESOURCES
java.srcDirs = JAVA_SOURCES

}
}

这里配置内容不再赘述,可以参考 Android 官网的说明进行设置,主要是针对独立运行时配置 Manifest 文件和添加入口页面的调整。

2.2.3 业务间的通信

对于拆分成独立部分的业务模块而言,彼此业务出现关联的场景还是比较多的,比如火车票推荐酒店,就需要从火车票模块跳转到酒店模块。

对于这样的业务场景,除了之前提到的将部分业务下沉到 BaseModule 以外,针对页面间跳转,我们采用了路由的方式。由于跳转的场景可能是原生页面、网页和 React Native 页面,我们制定了一套规则来进行通用的跳转。

跳转的链接按照以下的格式来实现:

sy://suanya.cn/xxx?url=xxx&type=1

其中的 type 则是跳转的类型, url 参数的值就是实际的跳转的地址。对于 网页和 React Native 页面,url 的值是比较容易直观的,对于原生页面,则引入了 ARouter 实现,对于需要传递的参数的场景,则采用 query parameters 的方式进行传递,在统一的地方进行处理,转换成 ARouter 传参的形式。

2.3 组件化架构调整中遇到的一些问题

2.3.1 业务模块的 Manifest 文件维护

在之前提到,业务模块独立运行时需要指定 Application 和启动页面,Manifest 文件内容如下:









其中的 ModuleApplication、ModuleLaunchActivity 和 ModuleHomeActivity 合并打包时,根据 sourceSets 的设置,是不会编译进来的,需要调整 AndroidManifest 文件,最简单的办法就是写两份 AndroidManifest 文件,通过 sourceSets 中的 manifest.srcFile 来指定。但是这样存在一个问题,例如添加一个 ModuleXXXActivity,这个在独立和非独立运行时都需要的 Activity,则需要在两个 AndroidManifest 中都添加一次,这样显然是不够合理的,对开发而言是不友好的。

我们通过 manifest merge 规则找到解决办法,业务模块只需要维护独立运行时的一份 AndroidManifest 文件即可,在合并的 App 的 AndroidManifest 中,对 application 节点,使用 replace 操作:

而对于只有模块独立运行才使用到的 activity ,则采用 remove 操作进行移除:


如此操作之后,就可以保证最终合并打包时,业务模块设置的 application 被替换成 app 的,而模块独立运行才应用到的 activity 则被移除了,只需要维护一份模块的 AndroidManifest 文件即可。

2.3.2 多应用差异化配置打包

在前面也提到,我们的业务场景对于同一个项目打包出不同的应用,这种需求的我们使用 ProductFlavors 进行了实现。

通过设置不同的 ProductFlavors,通过 manifestPlaceholders 来配置每个应用差异化的参数,例如接入微信的 appId,地图的 key 等。对于每个应用使用不同的主题色和资源问题,则采用在对应的 ProductFlavors 文件夹中以同名文件、同名资源名称的方式进行覆盖设置,这种同名的资源最终以 ProductFlavors 文件夹中的设置为准。

最后

今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。

最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司19年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

Android精讲视频领取学习后更加是如虎添翼!进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》
点击传送门,即可获取!

是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值