`
wbj0110
  • 浏览: 1602850 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Gradle学习系列之十——自定义Plugin

阅读更多

请通过以下方式下载本系列文章的Github示例代码:

git clone https://github.com/davenkin/gradle-learning.git

 


 

Gradle为每个build.gradle都会创建一个相应的Project领域对象,在编写Gradle脚本时,我们实际上是在操作诸如Project这样的Gradle领域对象。在多Project的项目中,我们会操作多个Project领域对象。Gradle提供了强大的多Project构建支持。

要创建多Project的Gradle项目,我们首先需要在根(Root)Project中加入名为settings.gradle的配置文件,该文件应该包含各个子Project的名称。比如,我们有一个根Project名为root-project,它包含有两个子Project,名字分别为sub-project1和sub-project2,此时对应的文件目录结构如下:

复制代码
root-project/
   sub-project1/
      build.gradle
   sub-project2/
      build.gradle
build.gradle
settings.gradle
复制代码

 

root-project本身也有自己的build.gradle文件,同时它还拥有settings.gradle文件位于和build.gradle相同的目录下。此外,两个子Project也拥有他们
自己的build.gradle文件。

 

要将sub-project1和sub-project2加入到root-project的子Project中,我们需要在settings.gradle中加入:

include 'sub-project1', 'sub-project2'

 

接下来,我们来定义一个Task用于显示每个Project各自的名称。我们可以在每个build.gradle进行定义,但是这却是一种比较笨的方法,此时我们也完全没有享受到Gradle的多Project构建功能所带来的好处。在Gradle中,我们可以通过根Project的allprojects()方法将配置一次性地应用于所有的Project,当然也包括定义Task。比如,在root-project的build.gradle中,我们可以做以下定义:

复制代码
allprojects {
   apply plugin: 'idea'
   

   task allTask << {
      println project.name
   }
}
复制代码

 

以上Gradle脚本将闭包中的代码应用在所有的Project中,包括root-project本身。我们首先将应用了idea Plugin用于生成IntelliJ工程,其次我们定义了名为allTask的Task,该
Task应用于每个Project,作用是输出各个Project的名称。执行“gradle allTask”,命令行输出如下:

:allTask
root-project
:sub-project1:allTask
sub-project1
:sub-project2:allTask
sub-project2

 

我们看到,该allTask对于每个Project都执行了一次,在执行时输出了当前Project的名称。

 

除了allprojects()之外,Project还提供了subprojects()方法用于配置所有的子Project(不包含根Project)。比如,我们可以定义Task来只输出各个子Project的名字:

subprojects {
   task subTask << {
      println project.name
   }
}

 

执行“gradle subTask”,命令行输出如下:

:sub-project1:subTask
sub-project1
:sub-project2:subTask
sub-project2

 

此时的输出中不再包含root-project的名字。

 

上文中已经提到,在Gradle脚本中,我们实际上是在操作一些领域对象,因此我们可以将groovy的所有语言特性用在Gradle的领域对象上,比如我们可以对Project进行过滤:

configure(allprojects.findAll { it.name.startsWith('sub') }) {
   subTask << {
      println 'this is a sub project'
   }
}

 

在上面的代码中,我们先找到所有Project中名字以“sub”开头的Project,然后再对这些Project进行配置,在配置中,我们向这些Project的subTask中加入了一条额外的打印语句。
此时如果再执行“gradle subTask”,命令行输出如下:

:sub-project1:subTask
sub-project1
this is a sub project
:sub-project2:subTask
sub-project2
this is a sub project

 

到此为止,我们所有的Task定义工作都是在root-project中进行的,而sub-project1和sub-project2中的build.gradle文件依然什么都没有。事实上,我们可以将所有对子Project的配置
均放在根Project中进行。在上面的例子中,我们通过allprojects()和subprojects()将所有的子Project都包含在了配置之内,其实我们还可以对单个Project进行单独配置。比如,在root-project
的build.gradle中加入:

project(':sub-project1') {
   task forProject1 << {
      println 'for project 1'
   }
}

 

以上脚本向sub-project1中加入了名为forProject1的Task,在执行“gradle forProject1”时,终端输出如下:

:sub-project1:forProject1
for project 1

 

这里有一个问题:我们是在root-project下执行的命令,因此照理说Gradle会认为forProject1是定义在所有的Project上,而此时只有sub-project1才拥有该Task,Gradle应该抛出异常指示在root-project和sub-project2上找不到该Task才对,为什么它还是执行成功了呢?原因在于:只有当一个Task没有在任何Project中定义时,Gradle才会将其当做异常。否则,Gradle会在所有拥有该Task的Project上执行该Task。

一旦有了多个Project,他们之间便会存在着依赖关系。Gradle的Project之间的依赖关系是基于Task的,而不是整个Project的。

现在,让我们来看一个Project依赖的例子。比如sub-project1中有taskA和taskB,taskA依赖于taskB:

复制代码
task taskA << {
   println 'this is taskA from project 1'
}

task taskB << {
   println 'this is taskB from project 1'
}

taskA.dependsOn taskB
复制代码

 

在执行“gradle taskA”时,终端输出:

:sub-project1:taskB
this is taskB from project 2
:sub-project1:taskA
this is taskA from project 1

 

这个很容易理解,两个Task都是属于sub-project1的。但是,让我们再向其中加入一些复杂性。我们在sub-project2中定义taskC和taskD,然后使taskA再依赖于taskC,又使taskB依赖于taskD:

复制代码
//sub-project1:
taskA.dependsOn ':sub-project2:taskC'
taskB.dependsOn ':sub-project2:taskD'

//sub-project2:
task taskC << {
   println 'this is taskC from project 2'
}

task taskD << {
   println 'this is taskD from project 2'
}
复制代码

 

此时再执行“gradle taskA”,终端输出如下:

复制代码
:sub-project2:taskD
this is taskD from project 2
:sub-project1:taskB
this is taskB from project 1
:sub-project2:taskC
this is taskC from project 2
:sub-project1:taskA
this is taskA from project 1
复制代码

 

分析一下:taskA依赖于taskB,而taskB又依赖于taskD,所以sub-project1的taskD首先得到了执行,然后再执行sub-project1的taskB。之后,又由于taskA依赖于taskC,故Gradle
再次转向sub-project1执行taskC,最后才执行taskA。

分享到:
评论

相关推荐

    手把手带你自定义 Gradle 插件 —— Gradle 系列(2).doc

    【Gradle 插件开发详解】 在Gradle构建系统中,插件扮演着至关重要的角色,它们提供了构建过程中的特定功能,如Java编译、Android...通过学习和实践自定义插件,开发者可以更好地适应项目的特殊需求,提升构建效率。

    composer-gradle-plugin,Gradle任务类型和与之交互的插件.zip

    本文将深入探讨一个特定的开源项目——`composer-gradle-plugin`,它是如何整合Gradle任务类型和插件,以便在Gradle环境中执行`gojuno/composer`的。 `composer-gradle-plugin`是一个针对PHP项目而设计的Gradle插件...

    gradle-plugin-0.10.0.zip

    本文将深入探讨一个特别的Gradle插件——"sdk-manager-plugin",版本号为0.10.0,以及它的使用场景和功能。 "gradle-plugin-0.10.0.zip"这个压缩包内包含了名为"sdk-manager-plugin-master"的源代码,这是一个开源...

    offline-android-gradle-plugin-preview.zip

    本压缩包"offline-android-gradle-plugin-preview.zip"包含了Android Gradle插件的一个预览版本——3.5.0-beta01,该版本发布于2020年06月22日,主要用于测试和评估新功能。 Android Gradle插件是Android Studio中...

    为什么说 Gradle 是 Android 进阶绕不去的坎 —— Gradle 系列(1).doc

    ale 插件: 提供具体构建逻辑,如 Android 插件负责处理 Android 项目的构建细节; Project: 表示一个独立的构建项目,可以包含多个子 ...通过逐步深入学习 Gradle 系列文章,你将能够更好地掌握这个强大的构建工具。

    gradle-gitVersioner-plugin,从git历史记录中提取有用的versioncode和versionname.zip

    为了解决这一问题,开源社区为我们带来了一个非常实用的插件——gradle-gitVersioner-plugin。 gradle-gitVersioner-plugin是一个Gradle插件,专门设计用于从Git仓库的历史记录中自动生成具有语义的版本号。它通过...

    gradle-1.8-bin

    在本案例中,我们关注的是 Gradle 的一个特定版本——1.8,这是一个针对Android开发的重要组件。 Gradle 1.8是Gradle早期的一个版本,发布于2013年,虽然现在已经比较老旧,但在当时它提供了许多先进的特性,例如...

    gradle-spelling-plugin:Gradle插件使用自定义黑名单检查拼写

    `gradle-spelling-plugin` 是一个针对Gradle构建系统的插件,它专注于代码质量的一个特定方面——拼写检查。这个插件允许开发者在构建过程中对源代码、文档等文本资源进行拼写检测,确保项目中的文字内容准确无误。 ...

    gradle-gaelyk-plugin-0.6.zip

    6. **自定义扩展**:由于Gradle Gaelyk插件基于Groovy,因此开发者可以轻松地扩展插件功能,添加自定义构建任务。 在压缩包`gradle-gaelyk-plugin-master`中,我们可以找到该插件的源代码和文档,这对于想要深入...

    gradle-3.4-bin.zip

    Gradle采用领域特定语言(DSL)——主要是Groovy和Kotlin DSL,使得构建脚本更加灵活且易于理解。`gradle-3.4-bin.zip`是Gradle 3.4版本的二进制发行版,它包含了运行Gradle所需的所有核心库和可执行文件。 **1. ...

    gradle-2.10.zip

    - **任务**:Gradle的任务是构建过程中的最小执行单元,如编译、测试、打包等,用户可以通过自定义任务实现特定需求。 - **缓存机制**:Gradle使用高效的缓存策略,避免重复下载和构建,提高构建速度。 - **插件...

    gradle-2.9-bin.zip

    3. 自动化任务:Gradle提供了一系列预定义的任务,如`assemble`、`clean`,同时允许自定义任务,实现编译、打包、测试等操作的自动化。 4. 插件应用:通过`apply plugin:`语句,可以应用各种Gradle插件,如Android...

    semver-git-plugin:用于通过git标签基于语义版本控制的版本控制项目的Gradle插件

    通过查看这些内容,开发者可以学习如何集成插件、自定义其行为,以及理解其内部工作原理。 总的来说,semver-git-plugin提供了一种高效且规范的方式来管理项目版本,通过自动化git标签过程,减少了手动维护版本号的...

    family-gradle-plugin:支持嵌套扩展对象的Gradle插件

    "family-gradle-plugin"正是这样一个专为Gradle设计的插件,它引入了一个独特的特性——支持嵌套扩展对象,极大地增强了Gradle的配置能力和可读性。本文将深入探讨这一插件的核心概念、实现原理以及如何在实际项目中...

    base-gradle_2.3.0-build-system:android gradle插件源代码-Android system source code

    《Android Gradle插件源代码解析——深入了解Android构建系统》 Android Gradle插件是Android开发中的重要组成部分,它使得Android应用的构建过程自动化、高效化。本文将深入探讨base-gradle_2.3.0-build-system源...

    IncludeMe:Gradle插件,可简化复合构建的使用

    - **gradle-plugin**:表示这是一个Gradle插件,用于扩展Gradle的功能。 - **gradle-sync**:可能指的是插件在项目同步方面的改进,确保依赖项正确解析和更新。 - **composite-builds**:即我们之前提到的复合构建,...

    GradlePluginDemo-master.zip

    《Gradle插件实战教程——基于GradlePluginDemo-master.zip》 在软件开发领域,构建工具扮演着至关重要的角色,它们帮助我们自动化处理项目构建、依赖管理等繁琐任务。其中,Gradle作为一款强大的构建工具,以其...

    plantuml-gradle-plugin:Gradle插件,可从代码构建PlantUML图(适用于最新文档)

    此外,`plantuml-gradle-plugin`还支持更高级的功能,比如自定义PlantUML的命令行参数,或者与其他Gradle插件(如Asciidoctor)结合,将PlantUML图直接嵌入到Markdown或AsciiDoc文档中。这样,你的项目不仅拥有实时...

    base-gradle_2.3.0-build-system:android gradle插件源代码

    通过对这些源代码的学习,开发者可以更深入地了解Android应用的构建流程,掌握如何自定义构建逻辑,优化编译速度,甚至创建自己的Gradle插件。此外,熟悉源代码也有助于解决在构建过程中遇到的异常问题,提升故障...

    gradle-plugins:Gradle实验和可重复使用的代码段

    "gradle-plugins:Gradle实验和可重复使用的代码段"项目正体现了Gradle的核心优势——插件系统。 Gradle插件是预定义的任务集合,可以添加到Gradle构建脚本中,以简化特定的构建任务,如Java应用的编译、打包或是Web...

Global site tag (gtag.js) - Google Analytics