将一个app分成多个模块,每个模块都是一个组件(Module),开发的过程中我们可以让这些组件相互依赖或者单独调试部分组件等,但是最终发布的时候是将这些组件合并统一成一个apk,这就是组件化开发。组件化开发中认为组件作为系统的一部分,是可独立运行的服务。
优点:一个复杂的系统由一个个组件集合而成,不同的组合可以构建出不同的系统。每个组件有独立的版本,可独立编译、打包,大大提高了系统的灵活性以及开发人员的开发效率。应用的更新可以精细到组件,组件的升级替换不会影响到其它组件,也不会受其它组件的限制。
缺点:组件化的实施对开发人员和团队管理人员提出了更高水平的要求,项目管理难度更大。组件间如何进行通信也是需要慎重考虑的。万事开头难,在对一个项目进行组件化分解时就好像庖丁解牛一般,你需要了解项目的“肌理筋骨”,才知道从何处下“刀”,才能更轻易的去分解项目,这就要求架构师对于项目的整体需求了如指掌。
组件可以分为业务组件和功能组件,功能组件为业务组件的运行提供功能支持。
Android studio中Module有两种形式(Application和Library)
1.application属性是可以独立运行的程序
apply plugin: ‘com.android.application’
2.library属性,不可以独立运行,一般是Android程序依赖的库文件
apply plugin: ‘com.android.application’
该属性是在每个Module的build.gradle文件配置的,组件模式开发时,业务组件应该为application属性,每个业务组件可以独立开发和调试;集成模式开发时业务组件应该为library属性,作为一个依赖包导入到壳工程。
如何让组件在组件模式和集成模式转变呢?总不可能每次都修改gradle文件吧,业务组件少一点还可以忍受,一旦项目变大,业务组件多达十几个的时候,手动改一遍必定费时费力。解决办法是在gradle.properties文件中添加一个isModule常量(true为组件式开发,false为集成式开发),因为在Android项目中的任何一个build.gradle文件中都可以把gradle.properties中的常量读取出来,我们可以通过读取这个常量的值来判断开发模式。
//在gradle.properties文件中添加下列字段
isModule=false
在每个业务组件的build.gradle文件开头添加下列字段
if (isModule.toBoolean()) {
apply plugin: 'com.android.application'
} else {
apply plugin: 'com.android.library'
}
在壳工程的build.gradle文件的dependencies中添加下列字段
if (!isModule.toBoolean()){
implementation project(':chat')
}
1.在Project目录下创建config.gradle,并且在Project目录下的build.gradle中引入:
ext {
def versions = [:]
versions.support = "29.0.2"
android = [
applicationId : "com.wjxk.cardbutler",
compileSdkVersion: 29,
minSdkVersion : 21,
targetSdkVersion : 29,
versionCode : 1,
versionName : "1.0.0",
]
dependencies = [
glide : 'com.github.bumptech.glide:glide:4.6.0',
rxJava : "io.reactivex.rxjava2:rxjava:2.2.3",
rxAndroid : "io.reactivex.rxjava2:rxandroid:2.1.0",
okhttploggingintercepter: "com.squareup.okhttp3:logging-interceptor:3.5.0",
retrofit : "com.squareup.retrofit2:retrofit:2.4.0",
retrofit_gson : "com.squareup.retrofit2:converter-gson:2.4.0",
retrofit_rxJava_adapter : "com.squareup.retrofit2:adapter-rxjava2:2.3.0",
]
support = [
constraintlayout: 'androidx.constraintlayout:constraintlayout:1.1.3',
appcompat : 'androidx.appcompat:appcompat:1.0.2',
]
}
在主工程的build.gradle文件开头添加下列代码
apply from: 'config.gradle'
然后在将各个组件里的build.gradle中的版本号改成下列代码(以下仅是部代码,第三方依赖包也要改动)
compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
minSdkVersion rootProject.ext.android.minSdkVersion
targetSdkVersion rootProject.ext.android.targetSdkVersion
versionCode rootProject.ext.android.versionCode
versionName rootProject.ext.android.versionName
在 AndroidStudio 中每一个组件都会有对应的 AndroidManifest.xml,用于声明需要的权限、Application、Activity、Service、Broadcast等,当项目处于组件模式时,业务组件的 AndroidManifest.xml 应该具有一个 Android APP 所具有的的所有属性,尤其是声明 Application 和要 launch的Activity,但是当项目处于集成模式的时候,每一个业务组件的 AndroidManifest.xml 都要合并到“app壳工程”中,要是每一个业务组件都有自己的 Application 和 launch的Activity,那么合并的时候肯定会冲突,试想一个APP怎么可能会有多个 Application 和 launch 的Activity呢?
为组件开发模式下的业务组件再创建一个 AndroidManifest.xml,然后根据isModule指定AndroidManifest.xml的文件路径,让业务组件在集成模式和组件模式下使用不同的AndroidManifest.xml,这样表单冲突的问题就可以规避了。
在每个业务组件的build.gradle文件的android模块添加下列代码
sourceSets {
main {
if (isModule.toBoolean()) {
manifest.srcFile 'src/main/module/AndroidManifest.xml'
} else {
manifest.srcFile 'src/main/AndroidManifest.xml'
}
}
}
在组件化开发的时候,组件之间是没有依赖关系,我们不能在使用显示调用来跳转页面了,因为我们组件化的目的之一就是解决模块间的强依赖问题,假如现在要从A业务组件跳转到业务B组件,并且要携带参数跳转,这时候怎么办呢?而且组件这么多怎么管理也是个问题,这时候就需要引入“路由”的概念了,由本文开始的组件化模型下的业务关系图可知路由就是起到一个转发的作用。
这里我介绍一个阿里开源的路由框架ARouter,具体用法自行百度,下一遍文章我会自己手写一个组件间通信的新方案,通过接口下沉的方式实现组件间通信。
组件化demo地址https://github.com/532268948/ComponentDemo