Gradle的基本流程
感觉很多时候创建好了项目,Gradle Build一下就好了。那么Build的时候发生了什么事呢?在此之前先看下Gradle项目的构成,了解下Gradle Wrapper。
这是一个Gradle项目运行的三个步骤:
image.png
- 从Gradle服务器下载指定版本的gradle
- 将下载的gradle存放并解压到Gradle User Home,对应着本地文件夹
~/.gradle
(复用,避免一个项目下载一次) - 使用下载的gradle
使用Gradle Wrapper的意义即在于把上面三步完成,不需要用户一步一步去完成。通常在使用的时候都是IDE帮我们生成好了,那么如果是自己新建一个Gradle Wrapper项目呢?直接在文件夹下执行gradle wrapper
:
.
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
└── gradlew.bat
即可生成最基础的gradle wrapper项目。这时执行./gradlew build
(不难看出,gradlew就是指的 gradle wrapper)就会去执行上面提到的三步。具体是第一步启动一个非常轻量级的JVM,然后这个Clinet JVM会和Gradle 的Deamon JVM连接将具体下载等等操作交给Deamon JVM。为什么要这么做呢?为什么不直接使用Clinet JVM做下载等操作呢?这是因为完成Gradle任务的JVM启动非常耗时,如果每次都新建JVM那么会浪费很多时间,这个Deamon JVM一旦创建会存在很长时间。这就是为什么你在首次同步Gradle的时候会在Build Output里面看到下面的log:
Starting Gradle Daemon...
Gradle Daemon started in 1 s 67 ms
> Task :prepareKotlinBuildScriptModel UP-TO-DATE
BUILD SUCCESSFUL in 12s
但是如果你同步成功后再按同步按钮你会发现log是这样的:
> Task :prepareKotlinBuildScriptModel UP-TO-DATE
BUILD SUCCESSFUL in 1s
不会再启动Daemon了。Daemon和项目的gradle wrapper要求的配置一一对应,不同配置的gradle wrapper会启动不同的Daemon。有时会遇到一些莫名其妙的gradle同步错误,可以试试 ./gradlew --stop
杀掉对应的Daemon JVM再试一次。
需要的Gradle版本完成下载后就会进入到项目Gradle的生命周期。Gradle的生命周期可以分为三大步:
-
Initialization 初始化阶段
在这个过程中,Gradle会确定哪些工程需要参与编译,并且为每个工程生成一个Project
类。Project
类是什么?为什么在项目中没有见过呢?其实你见过了,就是项目里的build.gradle
。那么Gradle是怎么确定哪些工程需要参与编译的呢?根据Settings
类。根据Settings
类?这个好像见过,对,就是项目中的settings.gradle
。现在知道settings.gradle
中的include ':app'
是怎么肥事了吧。当前项目的根目录,也就是settings.gradle所在的目录会默认生成一个
Project
对象。 -
Configuration 配置阶段
有了Project
的对象就可以根据里面闭包等等执行具体的任务了。比如下载依赖库、依赖的插件等等,这就是配置阶段。 -
Execution 执行阶段
这一步是根据传入的参数执行task的。比如assembleDebug
这样的。task是Gradle中执行的最小单元。这么说很抽象,举个例子吧,可以在biuld.gradle
中定义一个task:
task("yy"){
doFirst {
println("doFirst yy")
}
doLast {
println("doLast yy")
}
println("configure yy")
}
Sync项目就会在Gradle任务面板中找到这个task:
image.png
现在知道其他task都是怎么上去的了吧。双击yy或者在执行./gradlew yy
可以看到下面输出:
➜ GroovyTest ./gradlew yy
> Configure project :
configure yy
> Task :yy
doFirst yy
doLast yy
可以看到先输出了configure yy
这就是上面提到的配置阶段。如果这里面的代码有点陌生,可以看看上一篇介绍groovy基础的文章。
除了自己定义一些task外,还可以根据项目gradle的生命周期过程去执行一些task。比如项目构建完成后打印个log啥的。
afterEvaluate {
println("afterEvaluate")
if (state.failure != null) {
println ("Evaluation of $this FAILED")
} else {
println ("Evaluation of $this succeeded")
}
}
还可以定义task之间的依赖关系,比如taskA依赖taskB,这样执行taskA的时候会先执行taskB。
task("taskB") {
doFirst {
println("doFirst helloworld")
}
doLast {
println("doLast helloworld")
}
println("configure helloworld")
}
task("taskA") {
dependsOn("taskB")//依赖关系
doLast {
println("try")
}
}
好了,这里就简单介绍完了gradle的简单生命周期。接下来会介绍如何编写自己的gradle插件。