网站开发 平台建设陕西网站关键词自然排名优化
Gradle构建脚本基础
- Project: 根据业务抽取出来的一个个独立的模块
- Task:一个操作,一个原子性操作。比如上传一个
jar
到maven
中心库等 - Setting.gradle文件:初始化及整个工程的配置入口
- build.gradle文件: 每个
Project
都会有个build.gradle
的文件,是Project
构建的入口。Root Project
也有一个build.gradle
文件,可以获取到所有的Child Project
, 并且可以对所有的Child Project
进行统一配置:如应用的三方插件、三方依赖库等。如,我们可以在Root Project
的build.gradle
文件里配置:
allprojects {repositories {jcenter()}
}
这样项目中所有依赖的三方库都可以在jcenter
中下载了,省去了对每个Project
去配置的情况。
上面用到的是allprojects
,还可以配置subprojects
,他们的区别在于:allprojects
是对所有project
的配置,包括Root Project
。而subprojects
是对所有Child Project
的配置。更详细的请移步:https://blog.csdn.net/u013700502/article/details/85231687
1、创建一个task
Task
的创建方式,可以是:
task hello {doFirst {print 'hello:doFirst\n'}doLast {print 'hello:doLast\n'}
}
也可以是:
tasks.create("hello") {doFirst {print 'hello:doFirst'}doLast {print 'hello:doLast'}
}
他们执行的结果都是一样的:
bogon:test_gradle mq$ gradle -q hello
hello:doFirst
hello:doLast
task是Project对象的一个函数,原型为Task create(String name, Closure configureClosure),最后一个参数是闭包的时候,可以放到括号外面,并且括号可以省略,task
中的doFirst
和doLast
分别在任务前后执行。
如需完整版Gradle学习资料 请点击免费领取
2、创建Task的几种方式
- 1、调用
Project
对象的task(String name)
方法,如:
def Task hello = task(hello);hello << {print 'hello\n'
}
输出:
bogon:test_gradle mq$ gradle -q hello
hello
- 2、任务名字+闭包方式,如:
task hello {description '任务描述'doLast {print "方法原型: Task task(String name, Closure configureClosure)\n"print "任务描述: ${description}"}
}
输出结果:
bogon:test_gradle mq$ gradle -q hello
方法原型: Task task(String name, Closure configureClosure)
任务描述: 任务描述
- 3、
TaskContainer
方式创建:
tasks.create('hello') {description '任务描述'doLast {print "方法原型: Task create(String name, Closure configureClosure)\n"print "任务描述: ${description}"}
}
输出结果:
方法原型: Task create(String name, Closure configureClosure)
任务描述: 任务描述
tasks是Project的属性,其类型是TaskContainer。其中1和2的创建最终也是调用TaskContainer
方式创建的。
3、Task内部执行顺序
当我们执行Task
的时候,就是执行其拥有的actions
列表,是一个List
。把Task
执行之前、Task
本身执行、Task
之后执行分别称为doFirst、doSelf、doLast
,先来看个例子:
def Task hello = task myTask(type: CustomTask);hello.doFirst {print 'Task执行之前 do-First\n'
}hello.doLast {print 'Task执行之后 do-Last\n'
}class CustomTask extends DefaultTask {@TaskActiondef doself() {print 'Task执行自身 do-self\n'}
}
输出:
bogon:test_gradle mq$ gradle -q hello
Task执行之前 do-First
Task执行自身 do-self
Task执行之后 do-Last
通过结果发现确实是按照我们想要的顺序执行的。Gradle
在执行hello
这个任务的时候,Gradle
会解析其带有@TaskAction
注解的方法作为其Task
执行的Action
,并且把其加入到actionList
中。而doFirst、doLast
分别会在actionList
的最前面和最后面加入,所以之后就达到了按顺序执行。
4、Task任务依赖
任务之间是可以有依赖关系的,使用dependsOn
执行当前task
依赖的任务,如:
task hello << {print 'hello '
}task world(dependsOn: hello) {doLast {print 'world'}}
此时执行gradle -q world
,结果如下:
bogon:test_gradle mq$ gradle -q world
hello world
因为world
任务是依赖hello
的,所以当执行world
后,先去执行了hello
任务,再执行world
任务。dependsOn是Task类的一个方法,可以接受多个依赖的任务作为参数。 修改以下程序:
task hello << {print 'hello\n'
}task world(dependsOn: hello) {doLast {print 'world\n'}
}world.doFirst {print 'doFirst\n'
}world.doLast {print 'doLast2\n'
}
结果:
bogon:test_gradle mq$ gradle -q world
hello
doFirst
world
doLast2
通过结果可以看出,doFirst和doLast可以使用多次,并且按顺序执行。doLast
可以用 <<
操作符替代。
5、自定义属性
Project
和Task
允许添加额外自定义属性,通过对应的ext
属性即可,如
//自定义一个Project的属性
ext.buildTime = '2018'//自定义多个属性
ext {buildTime = '2018'month = '12'
}task time {doLast {print "构建时间${buildTime} 年${month}月 \n"}
}
执行gradle -q time
,执行结果:
bogon:test_gradle mq$ gradle -q time
构建时间2018 年12月
可见我们自定义的属性正确地取到了,自定义属性的作用域很广,只要能得到对应的Project
,就能获取到定义的属性值。在Android
中我们通常使用自定义属性值来定义我们的版本号、版本名称等,把这些放到一个单独的gradle
文件中,因为他们在发版前就会变动,放到单独的gradle
文件中便于管理,在AS根目录下新建config.gradle
如下:
//config.gradle
ext {android = [compileSdkVersion: 26,buildToolsVersion: "25.0.0",versionName : "6.2.1",versionCode : 6210,minSdkVersion : 16,targetSdkVersion : 23]}
在APP
对应的build.gradle
中取值:
//build.gradle
apply from: rootProject.getRootDir().getAbsolutePath() + '/config.gradle'compileSdkVersion rootProject.ext.android.compileSdkVersion
buildToolsVersion rootProject.ext.android.buildToolsVersion
就可以获取到自定义的属性值。
上例中,除了能获取到config.gradle
中的属性值,还可以在build.gradle
中调用config.gradle
中的方法,具体实现:
//config.gradle
ext {.......其他.........//注意方法和属性写法的区别copyApk = this.©Apk
}def copyApk() {}
在build.gradle
调用:
//build.gradle
apply from: rootProject.getRootDir().getAbsolutePath() + '/config.gradle'copyApk()
这样就实现了在build.gradle
中调用config.gradle
中的copyApk()
方法了。