谈起Gradle,那是Android工程默认的构建工具,在Android小伙伴之间可谓是无人不知,无人不晓。但是,真正理解Gradle的人却不多。下面,小亭就和您聊聊Gradle比ant、maven等传统构建工具好在哪儿,以及Gradle是个什么东东,包括哪些内容。是您对Gradle构建工程有个整体的把握和理解。
Gradle与ant、maven的区别?
Gradle比ant、maven强大很多。ant和maven是XML配置。Gradle使用Groovy这种程序语言,所以可编程,更加灵活。因为是程序语言,所以可以开发插件,有很多第三方插件库。
Gradle执行流程
Gradle的执行流程包括三部分:初始化、配置、运行。
初始化:解析所有project,构建project对象。执行settings.gradle文件。
配置:解析所有project中的task,构建Task拓扑图。
运行:执行所有task。
执行流程监听:如果我们要监听Gradle的执行流程,并在相应时机插入我们的处理逻辑,就需要以下这些接口。
beforeEvalueate {} 或者 gradle.beforeProject {} // 配置阶段之前执行
afterEvaluate {} 或者 gradle.afterProject {} // 配置阶段之后执行
gradle.buildFinished {} // 运行阶段之后执行
gradle.addListener // 增加自定义监听
Gradle组成
Gradle的组成包括三部分:Groovy、构建脚本块、Gradle api
Groovy语言是Gradle使用的程序语言,可编程,灵活方便。
构建脚本块:就是说我们要执行什么功能,就要使用Groovy语言写脚本块。
Gradle api是Gradle给我们提供的一套方便我们对构建过程进行编程处理的api。
Gradle API
包括project、task、属性、file、gradle生命周期、其他。
Project
一个build.gradle对应一个Project对象。
Task
我们可以编写Task,使其在Gradle运行的特定时间执行我们的逻辑。
定义:
task hello(group: ‘hello’, description:’hello task’) {println ‘hello task!’ // 配置阶段运行doFirst {println ‘the task group is:’ + group // 执行阶段运行}}
示例:统计打包时长
def startBuildTime, endBuildTimethis.afterEvaluate { Project project ->// 保证要找的task已经配置完毕def preBuildTask = project.tasks.getByName(‘’preBuild)preBuildTask.doFirst {startBuildTime = System.currentTimeMillis()}def buildTask = project.tasks.getByName(‘build’)buildTask.doLast {endBuildTime = System.currentTimeMillis()println “The build time is: ${endBuildTime - startBuildTime}”}}
延伸:我们可以根据统计出来的打包时长,删除一些测试task,来优化构建时间。
task的执行顺序:
构建一个apk需要用到好多task,那么这些task哪个先执行,哪个后执行就是由task的执行顺序决定的。
task task1 {doLast {println ’task1‘}}task task2 {doLast {println ’task2‘}}task task3(dependsOn: [task1, task2]) { // dependsOn还可以在闭包中写doLast {println ’task3‘}}
task的输入输出:
task writeTask { //为Task指定输入inputs.property(‘versionCode’, this.versionCode)inputs.property(‘versionName’, this.versionName)//为Task指定输出outputs.file destFiledoLast {def data = inputs.getProperties()File file = outputs.getFiles().getSingleFile()//将map转化为实体对象def versionMsg = new VersionMsg(data)def stringWriter = new StringWriter()def xmlBuilder = new MarkupBuilder(stringWriter)if (file.text != null && file.text.size() <= 0) {//文件中没有内容xmlBuilder.releases {release {versionCode(versionMsg.versionCode)versionName(versionMsg.versionName)}}file.withWriter {writer -> writer.append(stringWriter.toString())}} }}
将自定义Task挂接到构建过程中:
this.project.afterEvaluate { project ->def buildTask = project.tasks.getByName(‘build’)if (buildTask == null) {throw GradleException(‘The build task is not found’)}buildTask.doLast {writeTask.execute()}}
Settings
一个settings.gradle文件对应一个Settings对象。gradle的初始化过程就是在执行这个文件。
SourceSet
作用是对Gradle默认约定的文件位置进行修改。Gradle要求约定大于配置,就是说如果我们没有修改配置,那就按照默认的约定来。比如:从java文件夹下获取源码,从res文件夹下获取资源。但是,我们可以通过SourceSet修改代码、资源等的位置。
android {……sourceSets {main {jniLibs.srcDirs = [‘libs’] // 修改so库存放位置res.srcDirs = [‘src/main/res’,‘src/main/res-ad’,‘src/main/res-pay’] // 修改资源存放位置}}}
插件
1、定义插件类
class ExamplePlugin implements Plugin {@Overridevoid apply(Project project) {println ‘Hello ’ + project.nameproject.extensions.create(‘自定义别名’, 自定义类)}}
自定义Task类要继承自DefaultTask类。
class ExampleTask extends DefaultTask {ExampleTask() {group = ‘amy’description = ‘example’} // 在gradle执行阶段运行的代码@TaskActionvoid doAction() {......}}
2、在配置文件中指定插件类
3、在build.gradle文件中加入
apply plugin: ‘插件名’自定义别名 {……}
Android及Java插件对Gradle的扩展
Android对Gradle的扩展主要是配置变体,在
android {......}
配置脚本块中的设置都是对变体的设置。我们也可以通过拿到Android工程的变体来获取这些信息。
Java对Gradle的扩展相比Android简单很多,主要是打jar包一类的功能。
好了,以上就是Gradle的内容,通过上面的介绍,相信您对Gradle已经有了一个大致的了解。后续,我应该还会写一个介绍构建apk所有task流程的文章,敬请各位小伙伴们期待吧。