With this post I would like to start series of Gradle-related topics I wish I knew when I first started writing Gradle build scripts.

以这篇博客开始,我将写一系列关于Gradle的文章,用来记录接触Gradle构建脚本以来我所理解的Gradle。

Today we will talk about Gradle tasks and specificallyconfiguration and execution parts of the task. Since these terms might appear unknown to vast majority of readers, it will be easier to have real examples. Essentially (sorry for looking ahead), we will try to figure out what is the difference between these 3 examples:

今天要讲的就是Gradle tasks以及task的配置和运行。可能有的读者还不了解Gradle task,用真实的例子来展示应该更容易被理解。下面的代码展示了三个Gradle task,稍后会讲解这三者的不同:

task myTask {
println "Hello, World!"
} task myTask {
doLast {
println "Hello, World!"
}
} task myTask << {
println "Hello, World!"
}

My goal - is to create a task which prints "Hello, World!" when I execute it.

我的目的是创建一个task,当它执行的时候会打印出来”Hello, World!”。

When I first started, my first guess was to implement it like this:

当我第一次创建task的时候,我猜测应该是这样来写的:

task myTask {
println "Hello, World!"
}

Now, let's try to execute my new task!

现在,试着来执行这个myTask,在命令行输入gradle myTask,打印如下:

user$ gradle myTask
Hello, World!
:myTask UP-TO-DATE

It seems to be working! It prints "Hello, World!".

这个task看起来起作用了。它打印了”Hello, World!”。

But! It doesn't work as we might expect it to work. And here is why. Let's try to call gradle tasks to see what other tasks are available:

但是,它其实并没有像我们期望的那样。下面我们来看看为什么。在命令行输入gradle tasks来查看所有可用的tasks。

user$ gradle tasks
Hello, World!
:tasks ------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------ Build Setup tasks
-----------------
init - Initializes a new Gradle build. [incubating]
..........

Wait a second! Why my "Hello, World!" string is printed? I just called tasks, I didn't call my custom task!

等等,为什么”Hello, World!”打印出来了?我只是想看看有哪些可用的task,并没有执行任何自定义的task!

The reason why this is happening - is that Gradle task has 2 major stages in its lifecycle:

  • Configuration stage
  • Execution stage

原因其实很简单,Gradle task在它的生命周期中有两个主要的阶段:配置阶段 和 执行阶段。

I might not be super precise with terminology here, but this analogy helped me to understand tasks.

可能我的用词不是很精确,但这的确能帮助我理解tasks。

The thing is that Gradle has to configure all tasks specified in build script before actual build is started. It doesn't matter if certain task will be executed - it still needs to be configured.

Knowing that, how do I know which part of my task is evaluated during configuration and which one during execution?

And the answer is - the part specified within the top-level of the task - is task configuration section. I.e:

Gradle在执行task之前都要对task先进行配置。那么问题就来了,我怎么知道我的task中,哪些代码是在配置过程中执行的,哪些代码是在task执行的时候运行的?答案就是,在task的最顶层的代码就是配置代码,比如:

task myTask {
def name = "Pavel" //<-- this is evaluated during configuration
println "Hello, World!"////<-- this is also evaluated during configuration
}

That's why when I call gradle tasks I can see "Hello, World!" - this is our configuration section is executed. But that's not really what I want - I want "Hello, World!" to be printed only when I explicitly call my task.

这就是为什么我执行gradle tasks的时候,会打印出来”Hello, World!”-因为配置代码被执行了。但这并不是我想要的效果,我想要”Hello, World!”仅仅在我显式的调用myTask的时候才打印出来。

So how do I tell Gradle to do something when my tasks is executed?

In order to do that I need to specify task Action. The easiest way to specify task action is via Task#doLast() method:

为了达到这个效果,最简单的方法就是就是使用Task#doLast()方法。

task myTask {
def text = 'Hello, World!' //configure my task
doLast {
println text //this is executed when my task is called
}
}

Now my "Hello, World!" string will be printed only when I explicitly call gradle myTask

现在,”Hello, World!”仅仅会在我执行gradle myTask的时候打印出来。

Cool, now I know how to configure and make my task do real work only when I invoke it. What about that third option with <<symbol?:

Cool,现在我已经知道如何配置以及使task做正确的事情。还有一个问题,最开始的例子中,第三个task的<<符号是什么意思?

task myTask2 << {
println "Hello, World!"
}

This version is just a shortcut of doLast version, i.e. it is exactly the same as I would write:

这其实只是doLast的一个语法糖版本。它和下面的写法效果是一样的:

task myTask {
doLast {
println 'Hello, World!' //this is executed when my task is called
}
}

However, since now everything goes into execution part, I cannot configure my task the same way I did it with doLastoption (it is still possible to do, but in a slightly different way). So this option is good for really small tasks which do not require configuration, but if you have some task other than printing a "Hello, World!" - you might consider going with doLast.

但是,这种写法所有的代码都在执行部分,没有配置部分的代码,因此比较适合那些简小不需要配置的task。一旦你的task需要配置,那么还是要使用doLast的版本。

Happy gradling!

我是天王盖地虎的分割线

http://trickyandroid.com/gradle-tip-1-tasks/

http://blog.csdn.net/lzyzsd/article/details/46934187

Gradle tip #1: tasks的更多相关文章

  1. Gradle tip #3: Tasks ordering

    I noticed that the quite often problem I face when I work with Gradle - is tasks ordering (either ex ...

  2. org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to org.gradle.api.internal.file.collections.DefaultConfigurableFileCollection

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6709758.html Android Studio导入项目报错: org.gradle.api.inter ...

  3. Android studio Error:org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to

    http://blog.csdn.net/FlyRabbit_1/article/details/74536317 Error:org.gradle.api.internal.tasks.Defaul ...

  4. Gradle tip #2: understanding syntax

    In the Part 1 we talked about tasks and different stages of the build lifecycle. But after I publish ...

  5. Gradle Goodness: Excluding Tasks for Execution

    In Gradle we can create dependencies between tasks. But we can also exclude certain tasks from those ...

  6. Gradle Goodness: Adding Tasks to a Predefined Group

    In Gradle we can group related tasks using the group property of a task. We provide the name of our ...

  7. [Android Pro] Gradle tip #3-Task顺序

    reference to : http://blog.csdn.net/lzyzsd/article/details/46935405 原文链接 我注意到我在使用Gradle的时候遇到的大多数问题都是 ...

  8. Error:org.gradle.api.internal.tasks.DefaultTaskInputs$TaskInputUnionFileCollection cannot be cast to...异常处理

    这个是打开Android Studio项目报的错误提示,单纯从上面的提示还是不能太直接的知道什么问题.后来我想这个项目的Gradle版本与我当前AS使用的版本不一致,可能是这个问题. 修改build. ...

  9. gradle gradlew 的使用

    jcenter() 仓库比 mavenCentral() 仓库快,因此最好将jcenter 放前面,这样下载速度最快. 使用本地软件仓库:repositories { flatDir { dirs ' ...

随机推荐

  1. 大家一起和snailren学java-(二)一切都是对象

    “今天是周末,虽然外面阳光晴好,但是作为一名单身狗,还是除了寝室,就只有图书馆了.Anyway,既然没有对象,那我们就在java中找对象吧,哈哈.没有对象的人,看一切,都是对象!” 在面向对象程序设计 ...

  2. 记录ubuntu下的svn一些操作

    1.install svn serversudo apt-get install subversion 2.make repositorysudo mkdir /home/.svnsudo mkdie ...

  3. HashMap总结

    最近朋友推荐的一个很好的工作,又是面了2轮没通过,已经是好几次朋友内推没过了,觉得挺对不住朋友的.面试反馈有一方面是有些方面理解思考的还不够,平时也是项目进度比较紧,有些方面赶进度时没有理解清楚的后面 ...

  4. Android keystore 密码忘记了的找回办法

    keystore密码忘记了,准备给自己的应用发布一个新版本,在apk打包时,发现之前的用的keystore密码忘了.如果换一个keystore,则之前已经安装应用的用户就必须手工卸载原应用才能安装,非 ...

  5. XMLHttpRequest的跨域请求

    缘起 由于浏览器的同源策略,非同源不可请求. 但是,在实践当中,经常会出现需要跨域请求资源的情况,比较典型的例如某个子域名向负责进行用户验证的子域名请求用户信息等应用. 以前要实现跨域访问,可以通过J ...

  6. lucene索引

    一.lucene索引 1.文档层次结构 索引(Index):一个索引放在一个文件夹中: 段(Segment):一个索引中可以有很多段,段与段之间是独立的,添加新的文档可能产生新段,不同的段可以合并成一 ...

  7. Azure 自动化里添加ResourceManager模块

    最近想尝试通过Azure里的自动化功能来控制VM的定时开关机,找到网上的一篇文章,  按照文章操作到"Import Azure Resource manager module"的第 ...

  8. AngularJS跨域请求

    本文主要针对网上各种跨域请求的总结,并加入自己的验证判断,实现工作中遇到的跨域问题.所涉及到的领域很小,仅仅局限于:AngularJS CORS post 并同时需要实现json数据传送给服务器. 首 ...

  9. [转]PhoneGap使用PushPlugin插件实现消息推送

    本文转自:http://my.oschina.net/u/1270482/blog/217661 http://devgirl.org/2013/07/17/tutorial-implement-pu ...

  10. 用pygame学习初级python(一) 15.4.19

    最近有计划要学一下python,主要是要用flask.django一些框架进行后端的学习工作,但是在web应用之前希望进行一些基础的项目进行一些语法的练习,熟悉一下写法, 这个时候我就想先做几个小游戏 ...