读懂gradle的语法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读懂gradle的语法相关的知识,希望对你有一定的参考价值。
使用gradle构建android工程分为两个步骤,第一是配置阶段,定义project和task的属性和相互依赖关系;第二阶段是执行阶段,根据相应的定义执行project和task。
虽然很多时候我们按照现成的模板写就可以了,但是如果能读懂groovy语法,我们就可以举一反三,写出自己想要的效果。
groovy语言中有两大概念,第一是bean概念,即groovy会为每一个字段都默认生成getter和setter
class GroovyBeanExample {
private String name
}
task testbean{
def bean = new GroovyBeanExample()
bean.name = ‘this is name‘
println bean.name//输出 this is name
}
可以看到,即使我们为一个class定义了一个private的字段,我们在读写的时候依然可以使用“.字段”的方式,实际上就是使用默认的getter和setter进行读写的。
第二是闭包的delegate(代理)机制,使用闭包代理机制,我们可以将闭包中代码的作用对象设置为其他任意的对象。
class Child { private String name } class Parent { Child child = new Child(); void configChild(Closure c) { c.delegate = child c.setResolveStrategy Closure.DELEGATE_FIRST c() } } task testClosure{ def parent = new Parent() parent.configChild { name = "child name" } println parent.child.name//通过代理机制,name成了child的属性 }
在上面的例子中,当我们调用configChild()方法时,我们并没有指出name属性是属于Child的,但是它的确是在设置Child的name属性。事实上光从该方法的调用中,我们根本不知道name是属于哪个对象的,你可能会认为它是属于Parent的。真实情况是,在默认情况下,name的确被认为是属于Parent的,但是我们在configChild()方法的定义中做了手脚,使其不再访问Parent中的name(Parent也没有name属性),而是Child的name。在configChild()方法中,我们将该方法接受的闭包的delegate设置成了child,然后将该闭包的ResolveStrategy设置成了DELEGATE_FIRST。这样,在调用configChild()时,所跟闭包中代码被代理到了child上,即这些代码实际上是在child上执行的。此外,闭包的ResolveStrategy在默认情况下是OWNER_FIRST,即它会先查找闭包的owner(这里即parent),如果owner存在,则在owner上执行闭包中的代码。这里我们将其设置成了DELEGATE_FIRST,即该闭包会首先查找delegate(本例中即child),如果找到,该闭包便会在delegate上执行。对于上面的showDescription3,便是这种情况。当然,实际情况会稍微复杂一点,比如showDescription3()方法会在内部调用showDescription3的configure()方法,再在configure()方法中执行闭包中的代码。
你可能会发现,在使用Gradle时,我们并没有像上面的parent.configChild()一样指明方法调用的对象,而是在build.gradle文件中直接调用task(),apply()和configuration()方法等,这是因为在没有说明调用对象的情况下,Gradle会自动将调用对象设置成当前Project。比如调用apply()方法和调用project.apply()方法的效果是一样的。查查Gradle的Project文档,你会发现这些方法都是Project类的方法。
另外举个例子,对于configurations()方法(它的作用我们将在后面的文章中讲到),该方法实际上会将所跟闭包的delegate设置成ConfigurationContainer,然后在该ConfigurationContainer上执行闭包中的代码。再比如,dependencies()方法,该方法会将所跟闭包的delegate设置成DependencyHandler。
还有,Project还定义了configure(Object object,Closure configureClosure)方法,该方法是专门用来配置对象的(比如Task),它会将configureClosure的delegate设置成object,之后configureClosure中的执行代码其实是在object上执行的。和Groovy Bean一样,delegate机制的一个好处是可以增加所创建DSL的可读性。
以上是关于读懂gradle的语法的主要内容,如果未能解决你的问题,请参考以下文章