随着信息化的快速发展,IT项目变得愈来愈复杂,一般都是由多个子系统共同协做完成。对于这种多系统、多项目的状况,不少构建工具都已经提供 了不错的支持,像maven、ant。Gradle除了借鉴了ant或者maven的继承的方式定义子项目,也提供了一种更为方便的集中配置的方式,大大 减小了构建带来的复杂度。除此以外,Gradle还提供了清晰的Project树模型来映射多项目的组织结构。下面,让咱们了解一下如何使用Gradle 构建多项目。android
1. 多项目定义及结构ios
在Gradle中,使用文件settings.gradle定义当前项目的子项目,格式以下所示: web
include 'sub-project1', 'sub-project2', 'sub-project3',maven
它表示在当前的项目下创建三个子项目,分别为'sub-project1', 'sub-project2', 'sub-project3'。默认状况下,每一个子项目的名称对应着当前操做系统目录下的一个子目录。ide
当Gradle运行时,会根据settings.gradle的配置状况,构建一个单根节点的项目树。其中的每一个子节点表明一个项目(Project),每一个项目都有一个惟一的路径表示它在当前树中的位置,路径的定义方式相似:
工具
Root:<Level1-子节点>:<Level2-子节点>:<Level3-子节点>gradle
也能够简写成“:<Level1-子节点>:<Level2-子节点>:<Level3-子节点>”。借助这种路径的定义方式,咱们能够在build.gradle去访问不一样的子项目。另外,对于单项目,其实是一种特殊的、只存在根节点,没有子节点的项目树。
网站
例 如,咱们有个产品A,包括如下几个组件core,web,mobile。分别表明"核心逻辑"、"网站"、“手机客户端”。 由于每一个组件是独立的部分,这个时候最好咱们能定义多个子项目,让每一个子项目分别管理本身的构建。因而咱们能够这样定义 A/settings.gradle
ui
include 'core', 'web', 'mobile'spa
按照以前描述的,core组件对应A/core目录,web组件对应A/web目录,mobile组件对应A/mobile目录。接下来,咱们就能够在每一个组件内部,定义build.gradle负责管理当前组件的构建。
Gradle提供了一个内建的task 'gradle projects',能够 帮助咱们查看当前项目所包含的子项目,下面让咱们看看gradle projects的输出结果:
$ gradle projects
:projects
------------------------------------------------------------
Root project
------------------------------------------------------------
Root project 'A'
+--- Project ':core'
+--- Project ':mobile'
\--- Project ':web
结果一目了然,首先是Root级别的项目A,而后是A下面的子项目'core', 'mobile', 'mobile'
最终的文件以及目录结构以下所示:
A
--settings.gradle
--build.gradle
--core
--build.gradle
--web
--build.gradle
--mobile
--build.gradle
若是你不喜欢这种默认的结构,也能够按照以下方式定义子项目的名称和物理目录结构:
include(':core)
project(':core').projectDir = new File(settingsDir, 'core-xxx')
include(':web)
project(':web').projectDir = new File(settingsDir, 'web-xxx')
include(':mobile)
project(':mobile').projectDir = new File(settingsDir, 'mobile-xxx')
在这个例子中,子项目core实际上对应的物理目录为A/core-xxx,web实际上对应的是A/web-xxx,mobile也相似。
虽然咱们更改了子项目的物理目录结构,不过因为咱们在build.gradle中使用的是相似 “ :<SubProject>”的方式访问对应的子项目,因此目录结构的改变,对咱们Gradle的构建脚本并不会产生影响。
接下来,考虑一个更复杂的状况,随着产品的发展,mobile这个组件慢慢的划分红了Android和IOS两个部分,这时咱们只须要在目录A/mobile下定义新的settings.gradle,并加入以下部分:
include 'android', 'ios'
如今,mobile组件下将存在两个新的子项目 "android"和"ios"
因而,这时候'gradle projects'的目录结构就变成
A
--settings.gradle
--core
--build.gradle
--web
--build.gradle
--mobile
--settings.gradle
--ios
--build.gradle
--android
--build.gradle
2. 多项目的集中配置
对于大多数构建工具,对于子项目的配置,都是基于继承的方式。Gradle除了提供继承的方式来设置子项目,还提供了另一种集中的配置方式,方便咱们统一管理子项目的信息。下面看一个例子,打开A/build.gradle,输入以下部分:
allprojects {
task hello << {task -> println "I'm $task.project.name" }
}
subprojects {
hello << {println "- I am the sub project of A"}
}
project(':core').hello << {
println "- I'm the core component and provide service for other parts."
}
对于上面所示的代码,已经很表意了:
allprojects{xxx} 这段代码表示,对于全部的project,Gradle都将定义一个名称是hello的Task { println "I'm $task.project.name"} 。
subprojects{xxxx}的这段代码表示,对于全部的子project,将在名称为hello的Task上追加Action {println "- I am the sub project of A"}
注意:关于Task和Action的关系,请看我以前写的本系列的第一部分。
project(':core') 的这段代码表示,对于名称为core的project,将在名称为hello的Task上追加Action { println "- I'm the core component and provide service for other parts." }
3. 多项目的Task执行
以前咱们已经了解了多项目的结构以及如何经过路径去访问子项目。如今让咱们看看如何使用Gradle来执行多项目。
在 Gradle中,当在当前项目上执行gradle <Task>时,gradle会遍历当前项目以及其全部的子项目,依次执行全部的同名Task,注意:子项目的遍历顺序并非按照 setting.gradle中的定义顺序,而是按照子项目的首字母排列顺序。
基于刚才的例子,若是咱们在根目录下,执行gradle hello,那么全部子项目的“hello” Task都会被执行。若是咱们在mobile目录下执行gradle hello,那么mobile、android以及IOS的“hello” Task都会被执行。关于该例子的运行结果,这里就不贴出来了。你们若是有兴 趣的话能够试试。
4. 总结这篇文章主要描述了使用Gradle管理多项目的知识。相比Ant或者Maven,Gradle提供了更灵活的配置方式。更重要的是,Gradle还提供了不少内建的Task帮助咱们查看或者管理项目。此次就先聊到这里,下次咱们来看看Gradle的生命周期。