该项目需要一定android studio,gradle基础,一些具体实现细节文章没作具体介绍,详细知识点大家可以自行百度
Demo地址
Github:https://github.com/89682907/ModularityProject
码云:https://gitee.com/a_maker/ModularityProject
什么是组件化开发
组件化就是基于可重用的目的,将一个大的软件系统拆分成多个独立的组件,已减少耦合,每个组件都能独立运行,最终发布的时候是将这些组件合并统一成一个apk。
组件化开发的好处
1:每个Module可以单独调试开发,节省编译时间
2:加快业务迭代速度,各个业务模块组件更加独立,不再出现业务耦合情况
3:测试可以对单个模块进行快速测试
4:稳定的公共模块采用依赖库方式,提供给各个业务线使用,减少重复开发和维护工作量
5:迭代频繁的业务模块采用组件方式,各业务研发可以互不干扰、提升协作效率,并控制产品质量
6:控制代码权限,将代码的权限细分到更小的粒度等
组件化图解
Demo用法讲解
以MAC环境为例,项目结构图
app(主工程)
libCommon(公用封装和库)
libFaceRecognition(功能lib)
libPerfectionRetrofit(功能lib(公用))
modModuleA(业务module)
modModuleB(业务module)
把项目下载下来以后编译项目会提示编译失败,这时候打开android studio中的Terminal执行以下步骤
1:cd file/script/ 回车 (进入到项目目录file/script目录下)
2:./upload.sh (执行upload.sh脚本,如果是windows的话执行upload.bat )
等脚本执行完毕项目就可以正常编译通过,因为主项目引用的都是aar包,执行脚本首先是将moudle编译成aar包上传到本地maven库,默认会在项目根目录生成maven文件夹,实际应用的时候可以根据公司具体情况配置maven路径
关键文件解读
1:setting.gradle
这个文件配置了本地运行的时候加载哪些module,开发的时候大家可以根据实际情况控制要加载哪些module以此来提高编译速度
2:setting_auto_build.gradle
这个文件里配置脚本编译的时候加载哪些module,每新加一个module的时候应该在这里面增加配置,否则执行脚本编译的时候不加载该module
3:gradle.properies
#模块和lib版本控制
LIB_RETROFIT_NAME=libPerfectionRetrofit
LIB_RETROFIT_ARTIFACTID=PerfectionRetrofit
LIB_RETROFIT_VERSION=1.0.8-js
LIB_FACE_NAME=libFaceRecognition
LIB_FACE_ARTIFACTID=FaceRecognition
LIB_FACE_VERSION=1.1.3-js
MOD_A_NAME=modModuleA
MOD_A_ARTIFACTID=ModuleA
MOD_A_VERSION=1.0.8-js
MOD_B_NAME=modModuleB
MOD_B_ARTIFACTID=ModuleB
MOD_B_VERSION=1.1.3-js
这个文件主要配置各个module的name,artifactid,version其中version格式是(版本号-修改人姓名)这样团队协作的时候方便区分是谁最后修改该module,这些配置在打包上传maven的时候会用到,所以每添加一个module的时候都需要在这个文件里添加相应信息,修改的时候修改对应module的version这样在执行upload.sh的时候脚本就会识别出哪些module需要重新编译,项目切换到Project模式下可以看到file文件夹其中key里存放的是签名文件,script里存放了一些脚本文件前面提到的upload.sh和upload.bat就放在该目录下。
4:moduleInfo.gradle(在file文件夹下)
在这个gradle文件里定义了一个initModuleInfo方法
def initModuleInfo = {
//每添加一个lib或者一个mod的时候要在此处注册
List moduleList = new ArrayList<>()
moduleList.add(new ModuleInfo(gradleParam.LIB_RETROFIT_NAME, gradleParam.LIB_RETROFIT_ARTIFACTID, gradleParam.LIB_RETROFIT_VERSION, ":${gradleParam.LIB_RETROFIT_NAME}", true))
moduleList.add(new ModuleInfo(gradleParam.LIB_FACE_NAME, gradleParam.LIB_FACE_ARTIFACTID, gradleParam.LIB_FACE_VERSION, ":${gradleParam.LIB_FACE_NAME}", true))
moduleList.add(new ModuleInfo(gradleParam.MOD_A_NAME, gradleParam.MOD_A_ARTIFACTID, gradleParam.MOD_A_VERSION, ":${gradleParam.MOD_A_NAME}", false))
moduleList.add(new ModuleInfo(gradleParam.MOD_B_NAME, gradleParam.MOD_B_ARTIFACTID, gradleParam.MOD_B_VERSION, ":${gradleParam.MOD_B_NAME}", false))
rootProject.ext.set("MODULE_INFO_LIST", moduleList)
}
这个方法就是根据gradle.properies里module的信息初始化的,每添加一个module都要在此处注册。
所以每次添加一个module的时候有两处要修改
1:gradle.properies里添加相应信息
2:moduleInfo.gradle里注册一下
5:Project的build.gradle
allprojects {
repositories {
google()
jcenter()
// maven { url "https://jitpack.io" }
maven {
url rootProject.ext.repoUrl
}
// maven{
// url "http://nexus.enn.cn/content/groups/public/"
// }
}
}
这里用的是默认的本地maven,自定义配置的话可以在此处修改
ext {
compileSdkVersion = 27
minSdkVersion = 16
targetSdkVersion = 27
javaVersion = JavaVersion.VERSION_1_8
// App dependencies version
android_support_version = "27.0.2"
arouter_api = "1.3.0"
arouter_compiler = "1.1.4"
fastjson = "1.1.67.android"
}
这里设置了一些通用版本信息
6:app的build.gradle
dependencies {
api project(':libCommon')
// implementation project(':modModuleA')
// implementation project(':modModuleB')
implementation "${rootProject.ext.modModuleA}"
implementation "${rootProject.ext.modModuleB}"
implementation 'com.android.support.constraint:constraint-layout:1.0.2'
implementation 'com.android.support:multidex:1.0.2'
implementation 'com.google.code.findbugs:jsr305:3.0.1'
}
apply from: "${rootDir}/gradle/processResourceAndManifest.gradle"
apply from: "${rootDir}/gradle/generateApk.gradle"
这里都是引用的maven库里的aar包,如果是开发调试的时候可以用implementation project(':moduleName')这样修改代码后直接运行就是执行的最新代码,否则都是执行的aar里的代码
7:以libPerfectionRetrofit为例说下module的build.gradle配置
apply plugin: 'com.android.library'
apply from: "${rootDir}/gradle/baseModule.gradle"
android {
defaultConfig {
versionCode Integer.parseInt("${rootProject.ext.versionCode}")
versionName "${rootProject.ext.versionName}"
}
}
apply plugin: 'maven'
uploadArchives {
repositories.mavenDeployer {
repository(url: rootProject.ext.repoUrl)
pom.groupId = rootProject.ext.PROJ_LIB_GROUP
pom.artifactId = LIB_RETROFIT_ARTIFACTID
pom.version = LIB_RETROFIT_VERSION
}
}
dependencies {
implementation 'com.squareup.okhttp3:okhttp:3.9.1'
api 'io.reactivex.rxjava2:rxjava:2.1.7'
api 'com.alibaba:fastjson:'+ "$rootProject.ext.fastjson"
implementation('com.squareup.retrofit2:retrofit:2.3.0') {
exclude(group: 'com.squareup.okhttp3', module: 'okhttp')
}
implementation('com.squareup.okhttp3:logging-interceptor:3.9.1') {
exclude(group: 'com.squareup.okhttp3', module: 'okhttp')
}
implementation('com.squareup.retrofit2:adapter-rxjava2:2.3.0') {
exclude(group: 'io.reactivex.rxjava2', module: 'rxjava')
exclude(group: 'com.squareup.retrofit2', module: 'retrofit')
}
implementation('org.ligboy.retrofit2:converter-fastjson-android:2.0.2') {
exclude(group: 'com.squareup.retrofit2', module: 'retrofit')
exclude(group: 'com.alibaba', module: 'fastjson')
}
api('io.reactivex.rxjava2:rxandroid:2.0.1') {
exclude(group: 'io.reactivex.rxjava2', module: 'rxjava')
}
}
其中
applyplugin:'com.android.library'
如果想单独调试该module的话可以改成(对应的manifest也要添加activity的启动入口)
applyplugin:'com.android.application'
每个module的build.gradle里都要添加apply from: "${rootDir}/gradle/baseModule.gradle"这个引用里面是一些公用基本配置,可以根据实际情况修改
apply plugin: 'maven'
uploadArchives {
repositories.mavenDeployer {
repository(url: rootProject.ext.repoUrl)
pom.groupId = rootProject.ext.PROJ_LIB_GROUP
pom.artifactId = LIB_RETROFIT_ARTIFACTID
pom.version = LIB_RETROFIT_VERSION
}
}
这些是上传maven配置,其中artifactId和version填写gradle.properies里对应的key值,该module是功能组件的话groupId可以设置rootProject.ext.PROJ_LIB_GROUP 如果是业务组件的话可以设置成rootProject.ext.PROJ_MOD_GROUP具体可以根据实际情况修改。
8:local.properties
develop=true
LOCAL_REPO_URL=file\:///Users/xxx/work/maven/modularity
LOCAL_REPO_PATH=/Users/xxx/work/maven/modularity
这里配置maven文件存储的本地路径,develop=true表示是开发状态标识,这些配置不是必须的在gradle文件夹里upload.gradle和init.gradle里有用到,不配置的话都有默认值
在gradle文件夹下有几个gradle文件,都是项目编译的时候用的一些配置项,具体内容可根据实际情况修改
本项目跨组件通信使用的ARouter具体用法可以参考https://github.com/alibaba/ARouter
修改代码更新aar
开发阶段代码修改完毕要提交的时候需要更新下gradle.properies里对应module的version,然后执行upload.sh脚本,这样就会重新编译aar包
以上就是android组件化开发的一个简单用法,项目本身还有很多地方可以优化,大家可以根据自己的实际情况做相应的优化和修改,有问题的话欢迎大家留言。