< center>
gradle 相对于maven,ant的强大之处在于可以变成控制构建的整个流程,不再局限于xml配置文件
gradle项目和我们平时理解的 AndroidStudio 项目不同,从gradle执行的角度理解,每一个moudle都是一个独立的project,包括最外层的project 也是project, 里面的task都是独立存在的
初始化: 解析setting.gradle,获取所有的project
**配置:**通过扫描所有project中的build.gradle文件获取所有的task,形成有线无环图形成先后执行依赖关系
执行task: 按照上面的顺序执行所有的task
/**
* 配置阶段开始前的回调
*/
this.beforeEvaluate {
println "app初始化完成..."
}
/**
* 配置阶段完成以后的回调
*/
this.afterEvaluate {
println 'app配置完成...'
}
/**
* gradle指令执行完成后回调
*/
this.gradle.buildFinished {
println 'app执行阶段执行完毕...'
}
setting中配置项目 include 顺序,同时输出一句话,证明初始化时读取了setting
app工程中build.gralde的配置
appLibrary工程中build.gralde的配置
运行得到结果:
通过命令行 gradle projects
可以验证
/**
* 手动 实现一个获取项目下所有project的方法
*/
task getAllProject << {
println '''
------------------------------------------------------------
Root project
------------------------------------------------------------
'''
this.allprojects.eachWithIndex { project, index ->
if (index == 0) {
println "Root project ${project.name}"
}else {
println "+-------- Project ${project.name}"
}
}
}
执行task
gradle getAllProject
输出结果:
源码说明:
/**
* 手动 实现一个获取项目下所有子project的方法
*/
task getSubProject << {
println '''
------------------------------------------------------------
Sub project
------------------------------------------------------------
'''
this.subprojects .eachWithIndex { project, index ->
println "+-------- Project ${project.name}"
}
}
执行task
gradle getSubProject
输出结果:
/**
* 手动 实现一个获取项目根project的方法
*/
task getRootPro << {
println '''
------------------------------------------------------------
Root project
------------------------------------------------------------
'''
println "+-------- Root project ${this.rootProject.name}"
}
执行task
gradle getRootPro
输出结果:
/**
* 手动 实现一个获取项目父project的方法
*/
task getParentPro << {
println '''
------------------------------------------------------------
Parent project
------------------------------------------------------------
'''
println "+-------- Parent project ${this.getParent().name}"
}
app.build 中定义获取version的方法
/**
* 输出当前的version
*/
def printVersion () {
return version
}
rootProject配置代码
/**
* 根据projectd的名称查找对应的project
*
*/
task findTheProject() << {
this.project("app") { project ->
println '''
------------------------------------------------------------
获取单个 project ,并进行操作
------------------------------------------------------------
'''
project.version='1.0.1'
println "当前操作的 project 是 ${project.name}"
println "当前配置后的版本号是 ${project.printVersion()}"
//指定当前project的输出结果为apk
apply plugin: "com.android.application"
}
}
运行结果:
应用场景:
appLibrary.build 中定义获取version的方法
/**
* 输出当前的version
*/
def printVersion () {
return version
}
rootProject配置代码
/**
* 配置当前节点project及其所有的子project
*/
task configAllProject << {
allprojects {
version = '1.0.8'
println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
}
}
运行结果:
当然在实际的使员过程中,allProject的配置直接放在文件中定义,不必放在一个task中
细心的朋友会发现我们的项目被调用了三次,只是因为allProject 返回的是一个project的集合,默认省略了回调参数project
如下是标准的写法
/**
* 配置当前节点project及其所有的子project
*/
task configAllProject << {
allprojects { project->
println "当前配置的project是 ${project.name}"
version = '1.0.8'
println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
}
}
运行结果:
相信这样你就明白整个配置过程了,allProject本质其实就是一个方法,方法的参数只有一个闭包,因此可以把闭包写在外面,方法执行时遍历所有的project然后调用闭包进行 project.变量的赋值或者方法的调用,只用当对应的appLibrary被调用的时候,version才会被赋值
subprojects {
println "当前配置的project是 ${it.name}"
version = '1.1.8'
println "全局配置后 appLibrary 的Version是 ${this.project('appLibrary').printVersion()} "
}
运行结果:
明白了上面的那个方法,这个方法就不用过多的解释了
subprojects {Project project ->
version = '1.1.8'
//模拟实际用用的场景,将编译好的lib发送到maven仓库
if(project.plugins.hasPlugin('com.android.library')){
//依赖(引入)一个事先编辑的脚本文件,上传文件到Maven
apply from: 'publishToMaven.gradle'
}
}