我们知道,子模块要编译到主工程中,需要再主工程根目录下的settings.gradle文件中设置子模块的引用路径和模块名称。
下面的配置是引用主工程当前目录下demo目录下的模块。
include ':demo'
下面是引用其他目录下的模块。
include 'demo'
project(':demo').projectDir =file('../zpw/demo')
要实现主工程替换本地和远程仓库代码的功能,可以先增加一个开关depend用于决定使用哪一端的代码,然后还需要设置项目名,项目地址,在主工程中对应的模块名。
{
"depend": true,
"project": "demo",
"projectDir": "D:\Android\workspace\demo",
"module": "com.zpw.demo:demo"
}
然后在settings.gradle中运行下列代码。
apply from: AUTO_INCLUDE_URL
evaluate(autoIncludeScript)
我们可以将下面代码以文件的方式保存在maven仓库中。
ext {
autoIncludeScript = '''
import groovy.json.JsonSlurper
def dependFile = new File(gradle.rootDir, 'dependency.json')
if (!dependFile.exists()) {
println "file dependency.json missing, generating..."
dependFile <<
"""
[
{
"depend": false,
"//depend": "true: impmlementation project,false: implementation 'group:artifacts:version'",
"project": "",
"//project": "project name, e.g. umeng, business_weex",
"projectDir": "",
"//projectDir": "absolute path of project, e.g. D:\\\\MyData\\\\AndroidStudioProjects\\\\component-service\\\\umeng",
"module": "",
"//module": "group:artifacts of module, e.g. com.midea.service:umeng"
},
{
"depend": false,
"project": "",
"projectDir": "",
"module": ""
}
]
""".stripIndent()
} else {
println "file dependency.json exist"
}
def gitignore = new File(gradle.rootDir, '.gitignore')
boolean needAdd = true
if (gitignore.exists()) {
gitignore.eachLine {
if (it.contains('dependency.json')) {
println("dependency.json has already added in .gitignore")
needAdd = false
}
}
if (needAdd) {
println "add dependency.json into .gitignore"
gitignore << "\ndependency.json"
}
}
if (!dependFile.canRead()) {
println "file dependency.json is unreadable"
return
}
try {
def dependJson = new JsonSlurper().parseText(dependFile.text)
dependJson.forEach {
println "project=$it.project, depend=$it.depend"
if (it.depend && it.project != null && it.project.length() > 0
&& it.projectDir != null && it.projectDir.length() > 0
&& it.module != null && it.module.length() > 0) {
println "include $it.project"
gradle.include ":$it.project"
gradle.project(":$it.project").projectDir = new File(it.projectDir)
}
}
} catch (e) {
println "autoInclude exception: $e"
}
'''
}
最后要切换的时候只需要在AS中同步代码皆可拉取对应段的代码。
拉取到代码之后,因为我们的主工程的build.gradle中默认依赖了远程仓库的代码。
dependencies {
implementation "com.zpw.demo:demo"
}
我们需要在编译的过程中替换原来的依赖,gradle提供了替换依赖的工具,我们可以在编译的过程中进行替换,编写以下插件。
import groovy.json.JsonSlurper
import org.gradle.api.Plugin
import org.gradle.api.Project
class DependPlugin implements Plugin<Project> {
static final String TAG = "#DependPlugin"
@Override
void apply(Project project) {
def file = new File("$project.rootDir/dependency.json")
if (!file.exists()) {
println "$TAG: file dependency.json missing"
return
}
if (!file.canRead()) {
println "$TAG: file dependency.json is unreadable"
return
}
try {
def json = new JsonSlurper().parseText(file.text)
project.allprojects { p ->
p.afterEvaluate {
json.forEach {
println "$TAG: configProject=$p, project=$it.project, depend=$it.depend"
if (it.project != null && it.project.length() > 0
&& it.projectDir != null && it.projectDir.length() > 0
&& it.module != null && it.module.length() > 0) {
if (it.depend) {
println "$TAG: convert module to project"
convert(p, it.module, it.project)
}
}
}
}
}
} catch (e) {
println "$TAG: execute exception: $e"
}
}
private void convert(Project project, String moduleName, String projectName) {
project.configurations.all {
resolutionStrategy {
dependencySubstitution { ds ->
substitute module(moduleName) with ds.project(":$projectName")
}
}
}
}
}
然后再壳工程的build.gradle文件中引入并执行。
classpath "com.zpw.demo.depend:depend-plugin:0.0.1-SNAPSHOT"
apply plugin: 'plugin.depend'