Gradle使用说明

Gradle

1. gradle

Gradle是一个基于Apache AntApache Maven概念的项目自动化建构工具。它使用一种基于Groovy特定领域语言来声明项目设置,而不是传统的XML[2]

当前其支持的语言限于JavaGroovyScala[3],计划未来将支持更多的语言。[^1]

2. 优势

  • 自动处理包相依关系 - 取自 Maven Repos 的概念
  • 自动处理布署问题 - 取自 Ant 的概念
  • 条件判断写法直觉 - 使用 Groovy 语言

3. 使用

  • gradle daemon

    gradle daemon在后台和OS交互,提供一个JVM实例,可加快gradle build速度

  • gradle wrapper

    可直接使用gradle但建议使用gradle wrapper,这样可确保团队工作使用的是用一个版本的gradle

  • 位置

    • Windows: c://User/$USER/.gradle/
    • Linux: /home/$USER/.gradle/

    可以看到有x.x表示已经安装的版本

    或者在./wrapper/dists/x.x下的wrapper版本

    如图,我下载的gradle版本有2.3 4.10.3 5.6.3

    (Hint 如果你不用gradle用于其他生产开发,只用Android Studio,应该只有wrapper中的文件)

4. build.gradle/Groovy

下面我们结合Android Studio来说明一下gradle的使用

最核心的当然就是build.gradle文件,下面从一个简单的build.gradle[^2]为例开始说明

1
2
3
4
5
6
7
task hello {
description "Hey student! Run this one :D"
group "Our demo"
doLast {
println "Hello World!"
}
}

gradle是采用groovy语言的,所以和Java兼容,你在build.gradle里面甚至可以写class来定义类,下面是一个关于更复杂的build.gradle[^3]例子(仅用于说明groovy部分语法)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
task groovy << {}

println "Hello Groovy!"

class JavaGreeter {
public void sayHello() {
System.out.println("Hello Java!");
}
}

JavaGreeter greeter = new JavaGreeter()
greeter.sayHello()

def foo = 6.5

println "foo has value: $foo"

println "Let's do some math. 5 + 6 = ${5 + 6}"

println "foo is of type: ${foo.class} and has value: $foo"
foo = "a string"
println "foo is now of type: ${foo.class} and has value: $foo"

def doubleIt(n) {
n + n // Note we don't need a return statement
}

foo = 5
println "doubleIt($foo) = ${doubleIt(foo)}"

foo = "foobar"
println "doubleIt($foo) = ${doubleIt(foo)}"

def noArgs() {
println "Called the no args function"
}

def oneArg(x) {
println "Called the 1 arg function with $x"
x
}

def twoArgs(x, y) {
println "Called the 2 arg function with $x and $y"
x + y
}

oneArg 500 // Look, Ma! No parentheses!
twoArgs 200, 300
noArgs()
//noArgs // Doesn't work
//twoArgs oneArg 500, 200 // Also doesn't work as it's ambiguous
twoArgs oneArg(500), 200 // Fixed the ambiguity
  • Groovy

  • 在Groovy中你可以使用Java风格的代码

    • Groovy中 ;为可选项
    • 字符串中用 $ 包裹来执行简单的Groovy代码
  • 当函数参数数量大于等于1时,可以不用加()来调用函数

    • 可以像Java一样创建类,会自动创建getter和setter方法
    • 闭包 : 有点类似C语言中的函数指针,可直接被传递,然后正常用()调用
    • 注意这里println其实就是我们熟悉的System.out.println的缩写,还有注意在groovy里面我们很多情况下是不用加括号来代表函数调用的.

最后一个例子是一个简单Android项目的例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
repositories {
google()
jcenter()

}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.1'

// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()

}
}

task clean(type: Delete) {
delete rootProject.buildDir
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.kyle.gradletest"
minSdkVersion 28
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
}

5. gradle命令

1
2
3
gradle // 默认执行当前路径下的build.gradle
gradle -b test.gradle //手动指定执行文件
gradle tasks //查看当前执行文件的task,比如Java常用的task有compileJava/jar/javadoc等

6. gradle wrapper

运行任一x.gradle,附加tasks参数可发现gradle默认提供了wrapper任务

1
2
3
4
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.

Generates scripts (for Unix and windows) which allow you to build your project with Gradle, without having to install Gradle.

When a user executes a wrapper script the first time, the script downloads and installs the appropriate Gradle distribution and runs the build against this downloaded distribution. Any installed Gradle distribution is ignored when using the wrapper scripts.

The scripts generated by this task are intended to be committed to your version control system. This task also generates a small gradle-wrapper.jar bootstrap JAR file and properties file which should also be committed to your VCS. The scripts delegates to this JAR.

它会生成一系列脚本(分别用于Unix和Windows)gradlew和gradlew.bat,使我们可以无需安装Gradle即可使用Gradle构建项目

当我们执行包装脚本时,如果没有对应的Gradle发行版,它会自动地下载该版本 (与gradle无关) 并使用它构建,使用包装器脚本时,将忽略所有已安装的Gradle发行版。

7. 坑

1.代理

使用Android Studio你会经常浏览第三方代码,如果你的国际网速不是太好或者gradle使用代理出现问题,很大几率会导致gradle下载失败,可以手动尝试在$ProjectDir/gradle/wrapper/gradle-wrapper.properties更改gradle版本(不建议)

或者手动去官网下载,然后放置在*/dists/文件夹下面

2.版本问题
  • app/build.gradle 中的com.android.tools.build:gradle 指的是Android使用gradle的工具版本

  • $ProjectDir/gradle/wrapper/gradle-wrapper.properties 指的是gradle wraaper使用gradle的版本(有all和bin之分)

  • java版本

​ 以上三个版本都有对应关系,比如以下(实测)

​ gradle 5.6.3 暂不支持openjdk13,支持Java 8 - 11

​ gradle 2.3 不支持openjdk11,13,支持openjdk 7,8

gradle版本 Java支持版本 Java不支持版本
5.6.3 ?-8-9-10-11-? 13
2.3 ?-7-8-? 11,13

不过Android的话其实Java只能使用Java 7-8 所以目前还没有什么太大问题

3.参数选择顺序

全局property < local property < CLI < (file.gradle) in ext < (file.gradle) in task

4.在Arch中无权限执行

如果你使用Win/Linux双系统,在Linux上发现gradlew,却发现无论怎么都无法加入可执行权限

  • 原因:ntfs分区不支持linux权限系统,所以添加x权限无效
  • 解决:sh ./gradlew或者切换项目所在分区到其他分区

8. Fin

最后推荐一个系统学习Gradle的网课https://classroom.udacity.com/courses/ud867

[^1]: 参考链接 Gradle中文维基https://zh.wikipedia.org/wiki/Gradle
[^2]: 该代码来源于ud867-Gradle/1.01-Exercise-RunYourFirstTask
[^3]: 该代码来源于ud867-Gradle/1.03-Demo-GroovyFundamentals

原文作者: Kyle-Ye

原文链接: https://kyle-ye.github.io/2019/12/01/GradleIntro/

许可协议: License: CC BY 4.0本文采用 CC-BY 协议进行授权

作者

知阅百威

发布于

2019-12-01

更新于

2019-12-01

许可协议