需要准备
- 一个熟悉的 IDE 开发工具
- JDK 7及以上
- Gradle 3.2以上
组织代码逻辑的几种方式
- 从父级继承属性和方法。在编译多工程的项目中,子工程可以从父工程继承属性和方法。
- 配置注入。在编译多工程的项目中,一个工程(通常是 root 工程)可以向另一个工程注入属性和方法。
- 工程的 buildSrc 目录。可以把你的脚本类文件放到指定的目录下,Gradle 能自动的编译并加载到工程的类路径中。
- 共享脚本。在外部的编译文件中定义公共的配置,可以在多个工程中或多个编译脚本中加载使用。
- 自定义任务。把你的编译逻辑封装到自定义的任务中,然后在不同的地方重复使用这些任务。(见第六章自定义任务)
- 自定义插件。把你的编译逻辑封装到自定义的插件中,可以在不同的工程中应用该插件。这个插件必须在脚本的类路径中,我们可以通过 buildSrc 方式或者添加包含该插件的外部库来实现。(见第七章自定义插件)
- 执行外部脚本。在当前编译脚本中执行另一个 Gradle 脚本。
- 使用第三方的类库。在当前编译脚本中直接使用第三方的类库。
从父级继承属性和方法
在父级工程的编译脚本中定义的属性和方法在它的所有子工程中都可以使用,我们可以使用它来定义公共的配置、封装公共的方法,在子工程中复用。代码示例如下:
build.gradle
// Define an extra property
ext.srcDirName = 'src/java'
// Define a method
def getSrcDir(project) {
return project.file(srcDirName)
}
child/build.gradle
task show {
doLast {
// Use inherited property
println 'srcDirName: ' + srcDirName
// Use inherited method
File srcDir = getSrcDir(project)
println 'srcDir: ' + rootProject.relativePath(srcDir)
}
}
执行命令gradle -q show
输出结果:
> gradle -q show
srcDirName: src/java
srcDir: child/src/java
配置注入
你可以使用配置注入技术来向很多工程注入属性和方法,这种比继承方式更好些,因为注入方式是在编译脚本中明确声明的,你可以注入不同的逻辑到不同的工程中,也可以注入任何形式的配置,比如 repositories, plug-ins, tasks 等等。示例代码如下:
build.gradle
subprojects {
// Define a new property
ext.srcDirName = 'src/java'
// Define a method using a closure as the method body
ext.srcDir = { file(srcDirName) }
// Define a task
task show {
doLast {
println 'project: ' + project.path
println 'srcDirName: ' + srcDirName
File srcDir = srcDir()
println 'srcDir: ' + rootProject.relativePath(srcDir)
}
}
}
// Inject special case configuration into a particular project
project(':child2') {
ext.srcDirName = "$srcDirName/legacy"
}
child1/build.gradle
// Use injected property and method. Here, we override the injected value
srcDirName = 'java'
def dir = srcDir()
执行命令gradle -q show
结果如下:
> gradle -q show
project: :child1
srcDirName: java
srcDir: child1/java
project: :child2
srcDirName: src/java/legacy
srcDir: child2/src/java/legacy
编译工程 buildSrc 目录下的源码
我们希望在 build.gradle 文件中运行我们的 Groovy 类,我们可以把它添加到buildSrc
目录下,其结构如下:
|-buildSrc
| |- src
| |- main
| |- groovy
| |- HelloWorld.groovy
|- build.gradle
代码示例如下:
build.gradle
apply plugin: 'groovy'
dependencies {
compile 'org.codehaus.groovy:groovy-all:2.2.1'
}
task helloTask << {
HelloWorld g = new HelloWorld()
g.say()
}
HelloWorld.groovy
class HelloWorld {
void say() {
println 'hello world'
}
}
执行命令gradle helloTask
结果如下:
> gradle -q helloTask
hello world
共享脚本
你可以配置当前工程使用一个外部的编译脚本,并且外部脚本具有 Gradle 语言所有的功能。示例代码如下:
build.gradle
apply from: 'other.gradle'
other.gradle
println "configuring $project"
task hello {
doLast {
println 'hello from other script'
}
}
执行命令gradle -q hello
结果如下:
> gradle -q hello
configuring root project 'configureProjectUsingScript'
hello from other script
执行外部脚本
你可以使用GradleBuild
任务来实现执行处部脚本,可以使用dir
或buildFile
属性来指定具体的执行脚本,同时使用tasks
属性来指定执行哪个任务。示例代码如下:
build.gradle
task build(type: GradleBuild) {
buildFile = 'other.gradle'
tasks = ['hello']
}
other.gradle
task hello {
doLast {
println "hello from the other build."
}
}
执行命令gradle -q build
结果如下:
> gradle -q build
hello from the other build.
使用第三方的类库
如果你的编译脚本需要使用第三方的类库,你可以把它们添加到脚本的类路径中。在 Gradle 中通过使用buildscript()
方法声明脚本的类路径。示例代码如下:
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
一旦在编译脚本的类路径中声明后,我们就能在编译脚本中使用它,具体使用方法如下所示:
build.gradle
import org.apache.commons.codec.binary.Base64
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath group: 'commons-codec', name: 'commons-codec', version: '1.2'
}
}
task encode {
doLast {
def byte[] encodedString = new Base64().encode('hello world\n'.getBytes())
println new String(encodedString)
}
}
执行命令gradle -q encode
结果如下:
> gradle -q encode
aGVsbG8gd29ybGQK
小结
Gradle 为我们提供了多样化的方式来组织我们的逻辑代码,我们可以选择最适合你的方式来实现,尽量避免代码的冗余或者非常难维护了。我们最好把复杂的逻辑拆分到分开的工程中去实现。
网友评论