如何设置Gradle的级别
如果您使用 Android Studio 中的按钮运行 Gradle,系统将使用 Android Studio 设置中设置的 JDK 运行 Gradle。如果您在 Android Studio 内部或外部的终端中运行 Gradle,JAVA_HOME 环境变量(如果已设置)会确定运行 Gradle 脚本的 JDK。如果未设置 JAVA_HOME,它会对您的 PATH 环境变量使用 java 命令。
为了获得最一致的结果,请确保设置 JAVA_HOME 环境变量,并在 Android Studio 中将 Gradle JDK 设置为同一 JDK。
运行 build 时,Gradle 会创建一个名为“守护程序”的进程来执行实际构建。只要 build 使用相同的 JDK 和 Gradle 版本,此过程就可以重复使用。重复使用守护程序可减少启动新 JVM 并初始化构建系统的时间。
如果您使用不同的 JDK 或 Gradle 版本启动构建,则会创建额外的守护程序,从而消耗更多的 CPU 和内存。
提示 :同时处理多个项目时,如果可能,请在其 gradle-wrapper.properties 文件中指定相同的 Gradle 版本,以减少创建的 Gradle 守护程序数量。
即不同工程 gradle 版本设置相同,java版本也设置相同。
Projects 和 tasks
projects 和 tasks是 Gradle 中最重要的两个概念。
任何一个 Gradle 构建都是由一个或多个 projects 组成。每个 project 包括许多可构建组成部分。 这完全取决于你要构建些什么。举个例子,每个 project 或许是一个 jar 包或者一个 web 应用,它也可以是一个由许多其他项目中产生的 jar 构成的 zip 压缩包。一个 project 不必描述它只能进行构建操作。它也可以部署你的应用或搭建你的环境。不要担心它像听上去的那样庞大。 Gradle 的 build-by-convention 可以让您来具体定义一个 project 到底该做什么。
每个 project 都由多个 tasks 组成。每个 task 都代表了构建执行过程中的一个原子性操作。如编译,打包,生成 javadoc,发布到某个仓库等操作。
到目前为止,可以发现我们可以在一个 project 中定义一些简单任务,后续章节将会阐述多项目构建和多项目多任务的内容。
Hello world
你可以通过在命令行运行 gradle 命令来执行构建,gradle 命令会从当前目录下寻找 build.gradle 文件来执行构建。我们称 build.gradle 文件为构建脚本。严格来说这其实是一个构建配置脚本,后面你会了解到这个构建脚本定义了一个 project 和一些默认的 task。
要尝试这一点,请创建以下名为 build.gradle 的构建脚本。
第一个构建脚本
build.gradle
task hello {
doLast {
println 'Hello world!'
}
}
然后在该文件所在目录执行 gradle -q hello
PS C:\Users\liyd\Desktop\gradleTest> gradle -q hello
Hello world!
快速定义任务
用一种更简洁的方式来定义上面的 hello 任务。
快速定义任务
build.gradle
task hello {
println 'Hello world!'
}
上面的脚本又一次采用闭包的方式来定义了一个叫做 hello 的任务,本文档后续章节中我们将会更多的采用这种风格来定义任务
构建 Java 项目
gradle 官方构建流程
运行 gradle build 的输出结果:
Output of gradle build
> gradle build
:compileJava
:processResources
:classes
:jar
:assemble
:compileTestJava
:processTestResources
:testClasses
:test
:check
:build
BUILD SUCCESSFUL
Total time: 1 secs
Android Studio中构建流程
Android studio中生成一个AAR文件执行流程,使用build构建生成AAR文件时,相较于gradle官方构建流程执行的task要多了很多。
> Task :mylibrary:preBuild UP-TO-DATE
> Task :mylibrary:preDebugBuild UP-TO-DATE
> Task :mylibrary:compileDebugAidl NO-SOURCE
> Task :mylibrary:mergeDebugJniLibFolders UP-TO-DATE
> Task :mylibrary:mergeDebugNativeLibs NO-SOURCE
> Task :mylibrary:stripDebugDebugSymbols NO-SOURCE
> Task :mylibrary:copyDebugJniLibsProjectAndLocalJars UP-TO-DATE
> Task :mylibrary:compileDebugRenderscript NO-SOURCE
> Task :mylibrary:generateDebugBuildConfig UP-TO-DATE
> Task :mylibrary:generateDebugResValues UP-TO-DATE
> Task :mylibrary:generateDebugResources UP-TO-DATE
> Task :mylibrary:packageDebugResources UP-TO-DATE
> Task :mylibrary:parseDebugLocalResources UP-TO-DATE
> Task :mylibrary:processDebugManifest UP-TO-DATE
> Task :mylibrary:generateDebugRFile UP-TO-DATE
> Task :mylibrary:extractDebugAnnotations UP-TO-DATE
> Task :mylibrary:javaPreCompileDebug UP-TO-DATE
> Task :mylibrary:compileDebugJavaWithJavac UP-TO-DATE
> Task :mylibrary:mergeDebugGeneratedProguardFiles UP-TO-DATE
> Task :mylibrary:mergeDebugConsumerProguardFiles UP-TO-DATE
> Task :mylibrary:mergeDebugShaders UP-TO-DATE
> Task :mylibrary:compileDebugShaders NO-SOURCE
> Task :mylibrary:generateDebugAssets UP-TO-DATE
> Task :mylibrary:packageDebugAssets UP-TO-DATE
> Task :mylibrary:packageDebugRenderscript NO-SOURCE
> Task :mylibrary:prepareDebugArtProfile UP-TO-DATE
> Task :mylibrary:prepareLintJarForPublish UP-TO-DATE
> Task :mylibrary:processDebugJavaRes NO-SOURCE
> Task :mylibrary:mergeDebugJavaResource UP-TO-DATE
> Task :mylibrary:syncDebugLibJars UP-TO-DATE
> Task :mylibrary:writeDebugAarMetadata UP-TO-DATE
> Task :mylibrary:bundleDebugAar UP-TO-DATE
> Task :mylibrary:assembleDebug UP-TO-DATE
> Task :mylibrary:preReleaseBuild UP-TO-DATE
> Task :mylibrary:compileReleaseAidl NO-SOURCE
> Task :mylibrary:mergeReleaseJniLibFolders UP-TO-DATE
> Task :mylibrary:mergeReleaseNativeLibs NO-SOURCE
> Task :mylibrary:stripReleaseDebugSymbols NO-SOURCE
> Task :mylibrary:copyReleaseJniLibsProjectAndLocalJars UP-TO-DATE
> Task :mylibrary:compileReleaseRenderscript NO-SOURCE
> Task :mylibrary:generateReleaseBuildConfig UP-TO-DATE
> Task :mylibrary:generateReleaseResValues UP-TO-DATE
> Task :mylibrary:generateReleaseResources UP-TO-DATE
> Task :mylibrary:packageReleaseResources UP-TO-DATE
> Task :mylibrary:parseReleaseLocalResources UP-TO-DATE
> Task :mylibrary:processReleaseManifest UP-TO-DATE
> Task :mylibrary:generateReleaseRFile UP-TO-DATE
> Task :mylibrary:extractReleaseAnnotations UP-TO-DATE
> Task :mylibrary:javaPreCompileRelease UP-TO-DATE
> Task :mylibrary:compileReleaseJavaWithJavac UP-TO-DATE
> Task :mylibrary:mergeReleaseGeneratedProguardFiles UP-TO-DATE
> Task :mylibrary:mergeReleaseConsumerProguardFiles UP-TO-DATE
> Task :mylibrary:mergeReleaseShaders UP-TO-DATE
> Task :mylibrary:compileReleaseShaders NO-SOURCE
> Task :mylibrary:generateReleaseAssets UP-TO-DATE
> Task :mylibrary:packageReleaseAssets UP-TO-DATE
> Task :mylibrary:packageReleaseRenderscript NO-SOURCE
> Task :mylibrary:prepareReleaseArtProfile UP-TO-DATE
> Task :mylibrary:processReleaseJavaRes NO-SOURCE
> Task :mylibrary:mergeReleaseJavaResource UP-TO-DATE
> Task :mylibrary:syncReleaseLibJars UP-TO-DATE
> Task :mylibrary:writeReleaseAarMetadata UP-TO-DATE
> Task :mylibrary:bundleReleaseAar UP-TO-DATE
> Task :mylibrary:mergeReleaseResources UP-TO-DATE
> Task :mylibrary:verifyReleaseResources UP-TO-DATE
> Task :mylibrary:assembleRelease UP-TO-DATE
> Task :mylibrary:assemble UP-TO-DATE
> Task :mylibrary:bundleDebugLocalLintAar UP-TO-DATE
> Task :mylibrary:preDebugAndroidTestBuild UP-TO-DATE
> Task :mylibrary:extractDeepLinksDebug UP-TO-DATE
> Task :mylibrary:processDebugAndroidTestManifest UP-TO-DATE
> Task :mylibrary:compileDebugAndroidTestRenderscript NO-SOURCE
> Task :mylibrary:bundleLibResDebug NO-SOURCE
> Task :mylibrary:bundleLibRuntimeToJarDebug UP-TO-DATE
> Task :mylibrary:createFullJarDebug UP-TO-DATE
> Task :mylibrary:extractProguardFiles UP-TO-DATE
> Task :mylibrary:generateDebugAndroidTestResValues UP-TO-DATE
> Task :mylibrary:writeDebugLintModelMetadata UP-TO-DATE
> Task :mylibrary:lintAnalyzeDebug UP-TO-DATE
> Task :mylibrary:lintReportDebug UP-TO-DATE
> Task :mylibrary:lintDebug
> Task :mylibrary:lint
> Task :mylibrary:bundleLibCompileToJarDebug UP-TO-DATE
> Task :mylibrary:preDebugUnitTestBuild UP-TO-DATE
> Task :mylibrary:generateDebugUnitTestStubRFile UP-TO-DATE
> Task :mylibrary:javaPreCompileDebugUnitTest UP-TO-DATE
> Task :mylibrary:compileDebugUnitTestJavaWithJavac UP-TO-DATE
> Task :mylibrary:processDebugUnitTestJavaRes NO-SOURCE
> Task :mylibrary:testDebugUnitTest UP-TO-DATE
> Task :mylibrary:bundleLibResRelease NO-SOURCE
> Task :mylibrary:bundleLibRuntimeToJarRelease UP-TO-DATE
> Task :mylibrary:bundleLibCompileToJarRelease UP-TO-DATE
> Task :mylibrary:preReleaseUnitTestBuild UP-TO-DATE
> Task :mylibrary:generateReleaseUnitTestStubRFile UP-TO-DATE
> Task :mylibrary:javaPreCompileReleaseUnitTest UP-TO-DATE
> Task :mylibrary:compileReleaseUnitTestJavaWithJavac UP-TO-DATE
> Task :mylibrary:processReleaseUnitTestJavaRes NO-SOURCE
> Task :mylibrary:testReleaseUnitTest UP-TO-DATE
> Task :mylibrary:test UP-TO-DATE
> Task :mylibrary:check
> Task :mylibrary:build
BUILD SUCCESSFUL in 4s
65 actionable tasks: 1 executed, 64 up-to-date
gradle常见构建流程
clean
删除 build 目录以及所有构建完成的文件。
assemble
编译并打包 jar 文件,但不会执行单元测试。一些其他插件可能会增强这个任务的功能。例如,如果采用了 War 插件,这个任务便会为你的项目打出 War 包。
check
编译并测试代码。一些其他插件也可能会增强这个任务的功能。例如,如果采用了 Code-quality 插件,这个任务会额外执行 Checkstyle。
外部依赖
通常,一个 Java 项目拥有许多外部依赖。你需要告诉 Gradle 如何找到并引用这些外部文件。在 Gradle 中通常 Jar 包都存在于仓库中。仓库可以用来搜寻依赖或发布项目产物。下面是一个采用 Maven 仓库的例子。
添加 Maven 仓库
build.gradle
repositories {
mavenCentral()
}
添加依赖
build.gradle
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
自定义项目
Java 插件为你的项目添加了众多默认配置。这些默认值通常对于一个普通项目来说已经足够了。但如果你觉得不适用修改起来也很简单。看下面的例子,我们为 Java 项目指定了版本号以及所用的 JDK 版本,并且添加一些属性到 mainfest 中。
build.gradle
sourceCompatibility = 1.5
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
}
}
为 test 添加系统属性
test {
systemProperties 'property': 'value'
}
发布 jar 包
如何发布 jar 包?你需要告诉 Gradle 发布到到哪。在 Gradle 中 jar 包通常被发布到某个仓库中。在下面的例子中,我们会将 jar 包发布到本地目录。当然你也可以发布到远程仓库或多个远程仓库中。
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
Eclipse plugin
apply plugin: 'java'
apply plugin: 'eclipse'
sourceCompatibility = 1.5
version = '1.0'
jar {
manifest {
attributes 'Implementation-Title': 'Gradle Quickstart', 'Implementation-Version': version
}
}
repositories {
mavenCentral()
}
dependencies {
compile group: 'commons-collections', name: 'commons-collections', version: '3.2'
testCompile group: 'junit', name: 'junit', version: '4.+'
}
test {
systemProperties 'property': 'value'
}
uploadArchives {
repositories {
flatDir {
dirs 'repos'
}
}
}
多项目构建
现在来看一个典型的多项目构建的例子。项目结构如下:
multiproject/
api/
services/webservice/
shared/
备注: 本示例代码可在 Gradle 发行包的 samples/java/multiproject 位置找到
此处有三个工程。api 工程用来生成给客户端用的 jar 文件,这个 jar 文件可以为 XML webservice 提供 Java 客户端。webservice 是一个 web 应用,生成 XML。shared 工程包含的是前述两个工程共用的代码。
多项目构建定义
定义一个多项目构建工程需要在根目录(本例中与 multiproject 同级)创建一个setting 配置文件来指明构建包含哪些项目。并且这个文件必需叫 settings.gradle 本例的配置文件如下:
多项目构建中的 settings.gradle
settings.gradle
include "shared", "api", "services:webservice", "services:shared"
公共配置
对多项目构建而言,总有一些共同的配置.在本例中,我们会在根项目上采用配置注入的方式定义一些公共配置。根项目就像一个容器,子项目会迭代访问它的配置并注入到自己的配置中。这样我们就可以简单的为所有工程定义主配置单了:
多项目构建-公共配置
build.gradle
subprojects {
apply plugin: 'java'
apply plugin: 'eclipse-wtp'
repositories {
mavenCentral()
}
dependencies {
testCompile 'junit:junit:4.11'
}
version = '1.0'
jar {
manifest.attributes provider: 'gradle'
}
}
工程依赖
同一个构建中可以建立工程依赖,一个工程的 jar 包可以提供给另外一个工程使用。例如我们可以让 api 工程以依赖于 shared 工程的 jar 包。这样 Gradle 在构建 api 之前总是会先构建 shared 工程。
多项目构建-工程依赖
dependencies {
compile project(':shared')
}
打包发布
多项目构建-发布
task dist(type: Zip) {
dependsOn spiJar
from 'src/dist'
into('libs') {
from spiJar.archivePath
from configurations.runtime
}
}
artifacts {
archives dist
}