美文网首页
Gradle第9课:Gradle 组织逻辑代码的八种形式

Gradle第9课:Gradle 组织逻辑代码的八种形式

作者: 米饭超人 | 来源:发表于2018-08-28 11:08 被阅读60次

需要准备

  • 一个熟悉的 IDE 开发工具
  • JDK 7及以上
  • Gradle 3.2以上

组织代码逻辑的几种方式

  1. 从父级继承属性和方法。在编译多工程的项目中,子工程可以从父工程继承属性和方法。
  2. 配置注入。在编译多工程的项目中,一个工程(通常是 root 工程)可以向另一个工程注入属性和方法。
  3. 工程的 buildSrc 目录。可以把你的脚本类文件放到指定的目录下,Gradle 能自动的编译并加载到工程的类路径中。
  4. 共享脚本。在外部的编译文件中定义公共的配置,可以在多个工程中或多个编译脚本中加载使用。
  5. 自定义任务。把你的编译逻辑封装到自定义的任务中,然后在不同的地方重复使用这些任务。(见第六章自定义任务)
  6. 自定义插件。把你的编译逻辑封装到自定义的插件中,可以在不同的工程中应用该插件。这个插件必须在脚本的类路径中,我们可以通过 buildSrc 方式或者添加包含该插件的外部库来实现。(见第七章自定义插件)
  7. 执行外部脚本。在当前编译脚本中执行另一个 Gradle 脚本。
  8. 使用第三方的类库。在当前编译脚本中直接使用第三方的类库。

从父级继承属性和方法

在父级工程的编译脚本中定义的属性和方法在它的所有子工程中都可以使用,我们可以使用它来定义公共的配置、封装公共的方法,在子工程中复用。代码示例如下:

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任务来实现执行处部脚本,可以使用dirbuildFile属性来指定具体的执行脚本,同时使用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 为我们提供了多样化的方式来组织我们的逻辑代码,我们可以选择最适合你的方式来实现,尽量避免代码的冗余或者非常难维护了。我们最好把复杂的逻辑拆分到分开的工程中去实现。

相关文章

网友评论

      本文标题:Gradle第9课:Gradle 组织逻辑代码的八种形式

      本文链接:https://www.haomeiwen.com/subject/xvrfwftx.html