Gradle 使用攻略

本文主要讲解一下Gradle的使用方法及注意事项,方便查阅

gradle介绍

Groovy会把脚本编译成groovy.lang.Script的子类。groovy.lang.Script是一个抽象类,它有一个抽象方法run(). 如果有一个脚本的文件名是Main,它的内容是:

1
println 'Hello from Groovy'

它编译后生成的类是:

1
2
3
4
5
6
7
8
class Main extends groovy.lang.Script {
def run() {
println 'Hello from Groovy'
}
static void main(String[] args) {
InvokerHelper.runScript(Main, args)
}

脚本中的语句会成为run方法的实现。

Gradle脚本编译生成的类当然也继承自groovy.lang.Script,并同时实现了Gradle自己的script接口org.gradle.api.Script。

gradle脚本build过程

Gradle脚本的build流程分为3个阶段:

  1. 初始化阶段
    Gradle支持单个和多个工程的编译。在初始化阶段,Gradle判断需要参与编译的工程,为每个工程创建一个Project对象,并建立工程之间的层次关系。这个阶段执行Settings脚本。

  2. 配置阶段
    Gradle对上一步创建的Project对象进行配置。这个阶段执行Build脚本

  3. 执行阶段
    Gradle执行选中的task。

settings.gradle

这个文件是全局的项目配置文件,里面主要声明一些需要加入 gradle 的 module;
此处包含了所有参与工程编译的 Module。

用于初始化project树。

1
2
3
include ':app', ':base'
include ':volley'
include ':wechatauth'

include语法

groovy允许省略语句结尾的分号,并允许在方法调用时省略括号。
下面两行代码等价。

1
2
include ':app', ':mylibrary'
include(':app', ':mylibrary');

初始化脚本的Script对象会有一个Project代理对象。在Script对象没有定义的属性和方法调用就会被转到Project对象。上面的语句实际上调用的是Project对象的include方法,该方法的原型如下:

1
void include(String[] projectPaths)

这个方法将给定的工程添加到build中。
工程路径的格式是:
以一个可选的”:”的开始,它表示”:”前面有一个不需要名字的根工程;剩下的部分是以”:”分隔的工程名。
例如, “:app”中”:”的是可选的,它表示”:”前面有一个不需要名字的根工程。

运行”gradle projects”可以获得这个demo的project树:

1
2
3
Root project 'AndroidDemo' //工程名
+--- Project ':app'
\--- Project ':modulename'

local.properties

gradle的SDK和NDK环境变量配置

1
2
3
4
5
6
7
8
9
10
## This file is automatically generated by Android Studio.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file should *NOT* be checked into Version Control Systems,
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
sdk.dir=E\:\\Android\\android-sdk-windows

gradle.properties

设置gradle脚本中的参数,比如代理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## Project-wide Gradle settings.
#
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
#
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx1024m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
#
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
#Thu Feb 23 20:37:17 CST 2017
systemProp.https.proxyPort=8080
systemProp.http.proxyHost=dev-proxy.oa.com
org.gradle.jvmargs=-Xmx1536m
systemProp.https.proxyHost=dev-proxy.oa.com
systemProp.http.proxyPort=8080

build/gradle/wrapper/gradle-wrapper.propertites

声明了gradle的目录与下载路径以及当前项目使用的gradle版本,这些默认的路径我们一般不会更改的,有時候导入一个新项目,gradle版本不对,可以在这里修改。

1
2
3
4
5
6
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip

build.gradle[project]

这个文件是整个项目的gradle基础(全局)配置文件,内容主要包含了3个方面:

  • 一个是声明仓库的源,这里可以看到是指明的jcenter(), 之前版本则是mavenCentral(), jcenter可以理解成是一个新的中央远程仓库,兼容maven中心仓库,而且性能更优。
  • 另一个是声明了android gradle plugin的版本。
  • allprojects:中定义的属性会被应用到所有 moudle 中,但是为了保证每个项目的独立性,我们一般不会在这里面操作太多共有的东西。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

所有通过gradle导入的jar包都是从jcenter这个中央仓库上扒下来的。
如果你需要的jar包在这个网站上没有,那就无法通过gradle的方式来导入的。

ext定义全局属性

根目录的gradle文件,在module比较多的情况下,最好统一,可以在这个文件定义一些共用的属性,然后在子module中。

1
2
3
4
5
6
7
8
9
//全局配置
ext {
minSdkVersion =15
targetSdkVersion =24
compileSdkVersion =24
buildToolsVersion ="24.0.0"
versionCode =1
versionName="1.0"
}

然后在子Module的gradle文件中引用

1
2
3
4
5
6
7
8
9
10
11
12
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode rootProject.ext.versionCode
versionName rootProject.ext.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
}

ext定义全局属性列表

1
2
3
4
5
6
7
8
9
ext {
channelDespendencies = [
facebook: "com.facebook.android:facebook-android-sdk:${facebookVersion}",
googleAuth: "com.google.android.gms:play-services-auth:${googleVersion}",
googleGames: "com.google.android.gms:play-services-games:${googleVersion}",
googleGCM : "com.google.android.gms:play-services-gcm:${googleVersion}",
googleGCM : "com.google.android.gms:play-services-gcm:${googleVersion}",
]
}

子module中引用如下

1
2
3
4
5
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
compile rootProject.ext.channelDespendencies.facebook
compile project(':base')
}

def定义全局函数

在根目录的全局gradle文件中定义函数

不包含在ext大标签下面

1
2
3
4
5
6
7
8
9
def releaseTime() {
return new Date().format("yyyy-MM-dd-HH", TimeZone.getTimeZone("UTC"))
}
def svnVersion(String url){
def svnUrl = "test";
String result = "svn info --show-item last-changed-revision ${svnUrl}".execute().text
return Integer.parseInt((result.trim()!="")? result.trim() : "1")
}

子module引用

1
2
3
4
5
6
7
8
9
10
11
12
android {
compileSdkVersion rootProject.ext.androidCompileSdkVersion
buildToolsVersion rootProject.ext.androidBuildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.androidMinSdkVersion
targetSdkVersion rootProject.ext.androidTargetSdkVersion
versionCode rootProject.svnVersion("facebooklogin") // look here
versionName mVersionName
}
}

build.gradle[Module:app]

这个文件是app文件夹下这个Module的gradle配置文件,也可以算是整个项目最主要的gradle配置文件,比如自动打包debug,release,beta等环境,签名,多渠道打包,混淆等操作都可以在这里面写。

build.gradle[Module:xxx]

每一个Module都需要有一个gradle配置文件。

Gradle 插件版本 vs Gradle 版本

整体版本可以通过 File > Project Structure > Project 查看

Gradle 插件版本

指定Gradle插件版本有两种方式:

  • 在Android Studio中选择File > Project Structure > Project菜单;
  • 在顶层build.gradle中修改配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    buildscript {
    repositories {
    jcenter()
    }
    dependencies {
    classpath 'com.android.tools.build:gradle:2.2.0'
    }
    ...
    }

Gradle 版本

指定 Gradle 版本也有两种方式:

  • 在Android Studio中选择 File > Project Structure > Project 来指定Gradle版本
  • 在gradle/wrapper/gradle-wrapper.properties文件中编辑Gradle引用地址:
    1
    2
    3
    4
    5
    6
    #Mon Mar 27 11:40:24 CST 2017
    distributionBase=GRADLE_USER_HOME
    distributionPath=wrapper/dists
    zipStoreBase=GRADLE_USER_HOME
    zipStorePath=wrapper/dists
    distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip

对应关系

下图是官网提供的对应关系

版本 说明
gradle-wrapper.properties 配置 Gradle 版本
build.gradle 配置 Gradle 插件版本

引用