一.组件化简介
注:组件化开发只适用于大型团队协作开发大型项目的场景,如果只是个人或者两三人开发则没有必要使用
什么是组件化
业务按照功能划分为一个一个模块,模块之间没有依赖关系,相互平行,模块之间的通信通过一定技术手段实现的开发方式就叫组件化
为什么需要组件化?
传统的开发方式:多人协作开发同一个项目,代码杂乱不易管理,并且多个功能之间依赖程度较高,无法做到按功能分组来打包提测,必须同步进行,有可能开发周期较短的功能需要等待开发周期较长的功能,效率较低
组件化开发方式:各功能之间互不影响,独立进行,并且可以实现单独模块打包,一个模块的进度不会影响到另一个模块的进展,有效的提高了开发测试的效率,代码结构清晰,便于管理。
组件化的实现方式
上边提到组件化各模块之间相互不允许有依赖关系,那么模块之间的通信方式就是一个需要首先解决的问题。通常来说实现方式有下面几种:
1.EventBus(每一个消息传递都需要一个独立的EventBean,维护成本太高)
2.广播 (不好管理,都统一发出去了)
3.使用隐士意图方式(在AndroidManifest.xml里面配置xml写的太多了)
4.使用类加载方式 (除了容易写错包名类名之外,其他缺点较少)
5.使用全局Map的方式(要在Application中注册很多的对象,太费事)
6.ARouter目前应用最广的方式 ARouter
ARouter由阿里巴巴开源(https://github.com/alibaba/ARouter)
二.这篇文章不去关注如何使用ARouter,而是重点放在组件化基础配置的搭建上
1.实现组件独立打包
既然是搭建组件化项目,那么首先我们要分出几个功能模块来!创建一个工程,app为项目主模块,然后创建另外三个Module:home,mine,news,最后创建一个Library库作为最底层的基础库
他们的依赖关系是这样的
app
implementation project(':mine')
implementation project(':home')
implementation project(':news')
mine
implementation project(':library')
home
implementation project(':library')
news
implementation project(':library')
创建一个common.gradle文件做全局的一些配置
然后在项目根目录的build.gradle中引入这个文件
common.gradle
ext {
isRelease = true
}
定义一个isRelease变量来作为项目的环境配置,我们要实现,线上环境打包把所有模块都打进去,测试环境打包可以指定模块单独打包
那么怎么实现呢?
我们知道,每个module要单独能够打包的话,他就必须有这样一个配置,也就是说它必须是一个module而不是一个library
apply plugin: 'com.android.application'
那么我们就可以通过isRelease这个变量来if else判断了,我们在每个组件的build.gradle文件顶部配置如下:
if (isRelease) {
apply plugin :'com.android.library'
} else {
apply plugin: 'com.android.application'
}
android {
...
defaultConfig {
if (!isRelease) { // 能够独立运行 必须要有applicationId
applicationId "com.renzhenming.xxxx"
}
....
}
}
也就是说release环境下,这个组件作为library被app依赖,debug环境下,这个组件是一个单独的module,可以实现独立打包。这样一来我们mine home news 三个module下都配置好了
然后在app build.gradle下配置如下,只有release环境下才去依赖三个library
dependencies {
...
if (isRelease){
implementation project(':mine')
implementation project(':home')
implementation project(':news')
}
}
如此,只是通过改变common.gradle文件中的isRelease字段的值就可以控制是否进行模块打包了,我们将isRelease设置为false,然后编译下看看,可以看到home,mine,news三个组件可以单独打包了
然后把isRelease设置为true再次编译
2.组件独立打包如何运行
仅仅是独立打包是不行的,总要有一个启动的Activity吧,但是这个Activity在release环境下又不能让他起作用,也就是不能在组件的AndroidManifest中配置,那么我们是不是可以指定一个debug环境下的AndroidManifest文件呢?
当然是可以的,我们在每个组件的src/main下创建一个debug目录和一个AndroidManifest,在这里指定LAUNCHER Activity
在这个组件的build.gradle下配置debug环境时文件AndroidManifest的目录指向我们创建的这个AndroidManifest
android {
...
sourceSets {
main {
if (!isRelease) {
// 如果是组件化模式
manifest.srcFile 'src/main/debug/AndroidManifest.xml' // 生效
} else { // 正式环境下
manifest.srcFile 'src/main/AndroidManifest.xml' // 让我们之前 默认的路径下的清单文件再次生xiao
}
}
}
}
但是有一个问题,这个debug目录既然时测试环境打包用的,release环境我们肯定不希望它的代码被打进包里去,那么release的时候我们就要把这个目录移除,添加一行配置
android {
...
sourceSets {
main {
if (!isRelease) {
// 如果是组件化模式
manifest.srcFile 'src/main/debug/AndroidManifest.xml' // 生效
} else { // 正式环境下
manifest.srcFile 'src/main/AndroidManifest.xml' // 让我们之前 默认的路径下的清单文件再次生xiao
java {
// release 时 debug 目录下文件不需要合并到主工程
exclude "**/debug/**"
}
}
}
}
}