前言
想了一下暂时好像也没什么要逼逼的,那就直接拿起键盘来一梭子吧。
1.创建工程
首先在AS上创建一个项目并命名为Component,我们把AS默认生成的app module作为主(host)模块,然后再创建两个module分别命名为order、personal,好了此时已经有了三个独立的模块,那么如何将这三个模块关联起来是我们下一步要做的事情了。
2.build.gradle配置
三个moudle都能独自运行,模块化开发初衷是要做到模块之间既可以单独运行又可以集成在一起,那么现在三个可单独运行得模块是如何集成到一起的?目前来看AS是不允许将它们直接关联的,所以接下来要修改两个依赖模块的build.gradle中的apply plugin属性:
//apply plugin: 'com.android.application' //表示Android module能单独运行
//上边为创建事默认配置,将其改为如下
apply plugin: 'com.android.library' //表示Android library不能单独运行
这个时候我们创建得三个模块就可以通过Procejt Structure(Ctrl+alt+shift+s)来关联起来了,
至于如何依赖Android Library这里就不做细说了。
通过上边修改配置增加两个(order&personal)模块的依赖,目前主模块App已经可以调用home和personal中的界面了,现在这和要实现的目标还差很远,由于要同时管理多个模块的build.gradle文件,所以这里我们要引入一个公共的配置config.gradle。
3.config.gradle创建与配置
我们在工程的根目录下右键创建File并命名为config.gradle,在文件添加ext{}属性,这ext中就可以加入我们需要配置的公共项了,
ext{
//组件化|集成化开关
isDebug = false
// 包名,用于存放APT生成的类文件
packageNameForAPT = "per.xxx.modular.apt"
//项目中的服务器地址
url = [
debug:'http://127.0.0.1/',
release:'http://release/',
]
android = [
"compileSdkVersion": 29 ,
"buildToolsVersion": "29.0.2"
]
defaultConfig = [
"minSdkVersion": 21 ,
"targetSdkVersion": 29,
"versionCode": 1,
"versionName": "1.0",
"testInstrumentationRunner":"androidx.test.runner.AndroidJUnitRunner"
]
applicationId = [
"app":"per.xxx.modular_app",
"order":"per.xxx.modular_order",
"personal":"per.xxx.modular_personal"
]
//模块中的依赖库
dependencies = [
"appcompat":"androidx.appcompat:appcompat:1.1.0",
"constraintlayout":"androidx.constraintlayout:constraintlayout:1.1.3",
"recyclerview":"androidx.recyclerview:recyclerview:1.2.0-alpha01"
]
}
然后引入该配置文件,在工程的build.gradle中最外层添加
apply from: "config.gradle"
那么这个时候我们三个模块就可以通过该配置文件统一管理了。
4.如何使用config.gradle中配置项
在各个模块的build.gradle中可以通过rootProject.ext来获取config.gradle配置的属性,这里将rootProject.ext 赋值到一个变量def rootSet = rootProject.ext
,然后在android和dependencies标签中我们就可以替换掉原来的配置项了,如下
//order模块的配置
def rootSet = rootProject.ext
if(rootSet.isDebug){//这里可以通过布尔值来切换是否可以单独运行
apply plugin: 'com.android.application'
}else {
apply plugin: 'com.android.library'
}
android {
compileSdkVersion rootSet.android.compileSdkVersion
buildToolsVersion rootSet.android.buildToolsVersion
defaultConfig {
if(rootSet.isDebug){
applicationId rootSet.applicationId.personal
}
minSdkVersion rootSet.defaultConfig.minSdkVersion
targetSdkVersion rootSet.defaultConfig.targetSdkVersion
versionCode rootSet.defaultConfig.versionCode
versionName rootSet.defaultConfig.versionName
testInstrumentationRunner rootSet.defaultConfig.testInstrumentationRunner
//传入APT参数
javaCompileOptions {
annotationProcessorOptions {
arguments = [moduleName: project.getName(), packageNameForAPT: packageNameForAPT]
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
sourceSets {
main{
if(rootSet.isDebug){
manifest.srcFile 'src/main/debug/AndroidManifest.xml'
}else {
manifest.srcFile 'src/main/AndroidManifest.xml'
// exclude{
// java{
// '**/debug/**'
// }
// }
}
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//此处通过遍历Map方式来循环引入依赖,减少代码
//也可以通过implementation rootSet.dependencies.appcompat 单独引入
rootSet.dependencies.each{k,v -> implementation v }
api project(':common')//此为公共组建
//测试相关库
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
可以看到我们通过rootSet.android.键来引入需要配置的值,这样做好处是只用修改config.gradle中的内容即可,便于统一管理,其中有两处用到了isDebug属性,这里大家应该能猜到其用处就是来区分是否能单独调试该模块的,需要注意的是App模块中是不需要加这两处判断的,因为App自始至终都是可以单独运行的,但是需要在dependencies 中加入如下判断:
if (!rootSet.isDebug) {
implementation project(':order')
implementation project(':personal')
}
否则,切换为单独调试模式时,我们的app会提示模块之间不能相互依赖的错误。
至此项目的grdle配置已经差不多了。