gradle设置build执⾏命令_GRADLE脚本的语法和BUILD流程导语
Studio中使⽤了Gradle进⾏build。我阅读了groovy官⽅⽂档,Gradle官⽅⽂档及⼀些源代码,Android插件的官⽅⽂档及⼀些源代码,希望给⼤家介绍⼀下Gradle脚本的语法和处理流程。简单Groovy是⼀种运⾏在JVM上的语⾔, Gradle是使⽤Groovy实现的, Android插件提供了android特定的功能。
踢毽子简笔画1. 脚本的build流程
1.1Groovy和脚本
会把脚本编译成groovy.lang.Script的⼦类。groovy.lang.Script是⼀个抽象类,它有⼀个抽象⽅法run(). 如果有⼀个脚本的⽂件名是Main,它的内容是:
println 'Hello from Groovy'
它编译后⽣成的类是:
class Main extends groovy.lang.Script {undefined
def run() {undefined
println 'Hello from Groovy'
}
static void main(String[] args) {undefined
InvokerHelper.runScript(Main, args)
}
脚本中的语句会成为run⽅法的实现。
Gradle脚本编译⽣成的类当然也继承⾃groovy.lang.Script,并同时实现了Gradle⾃⼰的script接⼝adle.api.Script。
1.2 Gradle脚本对象的代理对象
每⼀个Gradle脚本对象都有⼀个代理对象。Settings脚本的代理对象是Setting对象,Build脚本的代理对象是Project对象。每⼀个在脚本对象未找到的属性和⽅法都会转到代理对象。
Groovy和Java的⼀个不同之处就是Groovy可以动态的添加⽅法和属性。动态添加的⽅式之⼀是覆盖pr
opertyMissing和methodMissing ⽅法,Gradle就是采⽤这种⽅式实现了脚本对象的代理对象。下⾯是Gradle脚本对象的基类BasicScript的实现代码⽚段:
public abstract class BasicScript vy.scripts.Script adle.api.Script, FileOperations, ProcessOperations {undefined
......
private Object target;
private DynamicObject dynamicTarget;
......
public Object propertyMissing(String property) {undefined
if ("out".equals(property)) {undefined
return System.out;
} el {undefined
氯气与铁反应
Property(property);
}
}
......
public Object methodMissing(String name, Object params) {undefined
return dynamicTarget.invokeMethod(name, (Object[])params);
}
}
1.3 Gradle脚本的build流程
Gradle脚本的build流程分为3个阶段:
(1)初始化阶段曝晒的意思
Gradle⽀持单个和多个⼯程的编译。在初始化阶段,Gradle判断需要参与编译的⼯程,为每个⼯程创建⼀个Project对象,并建⽴⼯程之间的层次关系。这个阶段执⾏Settings脚本。
(2)配置阶段
Gradle对上⼀步创建的Project对象进⾏配置。这个阶段执⾏Build脚本
(3)执⾏阶段
Gradle执⾏选中的task。
1.4⼀个demo
下⾯是demo⼯程的⽂件层次,这个demo会被后⾯的部分使⽤。这个例⼦包含⼀个app⼦⼯程和⼀个library⼦⼯程。adle是Setttings脚本,三个adle都是Build脚本。
--adle
--adle
--app
小科学家
--adle
--mylibrary
--adle
2. Settings脚本
istp论文2.1 Settings脚本的内容信息技术的发展趋势
Settings脚本通常⽐较简单,⽤于初始化project树。demo中adle的内容是:
include ':app', ':mylibrary'
2.2 groovy的相关语法
groovy允许省略语句结尾的分号,并允许在⽅法调⽤时省略括号,上⾯的代码等价于:
include(':app', ':mylibrary');
2.3 Gradle的相关语法
初始化脚本的Script对象会有⼀个Project代理对象。在Script对象没有定义的属性和⽅法调⽤就会被转到Project对象。上⾯的语句实际上调⽤的是Project对象的include⽅法,该⽅法的原型如下:
void include(String[] projectPaths)
这个⽅法将给定的⼯程添加到build中。⼯程路径的格式是: 以⼀个可选的”:”的开始,它表⽰”:”前⾯有⼀个不需要名字的根⼯程;剩下的部分是以”:”分隔的⼯程名。例如, “:app”中”:”的是可选的,它表⽰”:”前⾯有⼀个不需要名字的根⼯程。
运⾏”gradle projects”可以获得这个demo的project树:
Root project 'AndroidGradleDemo'
+--- Project ':app'
\--- Project ':mylibrary'
3. Build脚本
3.1 app⼯程的Build脚本
apply plugin: 'com.android.application'
android {undefined
compileSdkVersion 23
......
buildTypes {undefined
debug {undefined
降火的水果applicationIdSuffix ".debug"
}
relea {undefined
minifyEnabled fal
//getDefaultProguardFile() will return the full path of ''
proguardFiles getDefaultProguardFile(''), 'proguard-rules.pro'
}
}
}
.......
3.2 Groovy相关的语法
1)Map
Groovy可以直接使⽤Java中的各种集合类型,例如Map和List等等。在初始化语法上有⼀些扩展
def key = 'name'
//创建⼀个Map。注意"Guillaume"的key是字符串"key"⽽不是变量key的值
def person = [key: 'Guillaume']
asrt !ainsKey('name')
ainsKey('key')
//创建⼀个Map。我们使⽤()包围了key。这种情况下,"Guillaume"的key是变量key的值"name"
def person2 = [(key): 'Guillaume']
ainsKey('name')
asrt !ainsKey('key')
(2)闭包
(2.1)Syntax
Groovy中的闭包是⼀个匿名的代码块。它的语法规则是:
{ [closureParameters -> ] statements }
)[closureParameters→]是可选的以”,”分隔的参数列表
*)statements是0或多条Groovy语句
下⾯是闭包的⼀些例⼦:
{ item++ }
//A closure using an implicit parameter (it)
{ println it }
//In that ca it is often better to u an explicit name for the parameter
{ it -> println it }
{ String x, int y ->
println "hey ${x} the value is ${y}"
}
{ reader ->
def line = adLine()
偶尔想起你}
(2.2)Owner, delegate and thisGroovy中的闭包有三个重要的概念: Owner, delegate and this *)this是指定义闭包的类
*)Owner是指直接包含闭包的类或闭包
*)delegate是指⽤于解析闭包中属性和⽅法调⽤的第三⽅对象
下⾯的代码段说明了this和闭包的区别:
class Enclosing {undefined
void run() {undefined
def whatIsOwnerMethod = { getOwner() }
/
/calling the closure will return the instance of Enclosing where the the closure is defined asrt whatIsOwnerMethod() == this
def whatIsOwner = { owner }
asrt whatIsOwner() == this
}
}
class NestedClosures {undefined
void run() {undefined
def nestedClosures = {undefined
def cl = { owner }
cl()
}
//then owner corresponds to the enclosing closure, hence a different object from this! asrt nestedClosures() == nestedClosures
}
}
下⾯的代码演⽰了delegate的作⽤。
class Person {undefined
String name
}
def p = new Person(name:'Igor')
def cl = { UpperCa() }
cl.delegate = p
//在设置了delegate后,闭包中的name属性被解析成作为delegate的Person的属性
asrt cl() == 'IGOR'
Gradle中⼤量使⽤闭包的delegate来实现对各种对象的配置。
(3)转化成Java语法后的代码
Map map = new HashMap();
map.put("plugin", "com.android.appliaction");
apply(map);//这个⽅法会代理给Project对象
android({undefined
//这个闭包的delegate是Android插件添加的extension
compileSdkVersion(23);
......
buildTypes({undefined
/
/这个闭包的delegate是 NamedDomainObjectContainerConfigureDelegate.
debug({undefined
applicationIdSuffix(".debug")