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

需要准备

  • 一个熟悉的 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 为我们提供了多样化的方式来组织我们的逻辑代码,我们可以选择最适合你的方式来实现,尽量避免代码的冗余或者非常难维护了。我们最好把复杂的逻辑拆分到分开的工程中去实现。

如果你有疑问欢迎加微信咨询:


u.wechat.com/MDHWBbNbJR (二维码自动识别)


也可以关注我的公众号想我提问:


weixin.qq.com/r/EEzl-dL (二维码自动识别)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值