构建工具(五):Android项目中的Gradle文件

一开始先进行Gradle和Maven的对比,然后,对Gradle,Gradle Wrapper,Android Plugin for Gradle的一些概念进行区分,最后通过分析Android项目中的各个Gradle文件。

Gradle文件介绍

主角Gradle终于上场了,在Google发布的Android Studio开发工具中,Gradle替换Eclipse锁使用的ant作为默认的Android构建工具,其吸纳了ant和Maven的优点。现在ant几乎销声匿迹,Maven也日薄西山,而Gradle的发展却如日中天。感觉大多数场景,Gradle替换Maven的趋势,指日可待了。

Gradle与Maven对比

那为啥前面还要花了几章简述Maven?

  • 通过Maven介绍一下,什么是构建工具,有什么作用。
  • Gradle是在Maven上发展起来的,兼容Maven,只有知己知彼,才能更好体验Gradle的优势
  • 一些非Android项目或者老的项目还使用到Maven。

Maven和Gradl直观上最大的区别,就是依赖管理的写法,由于Gradle本身是基于Groovy脚本语音进行构建的,并通过DSL进行描述和控制构建逻辑,书写起来更加自由。抛弃了Maven的xml格式的繁琐写法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="UTF-8"?>
<dependencies>
<dependency>
<groupId>com.android.support</groupId>
<artifactId>appcompat-v7</artifactId>
<version>26.1.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
1
2
3
4
dependencies {
compile 'com.android.support:appcompat-v7:26.+'
testCompile 'junit:junit:4.11'
}

Gradle比Maven不仅仅只是语法上的改变,还有

  • 性能方面得到很大提升
  • 构建周期没有限制太死,比较灵活
  • 依赖范围被简化
  • 支持版本号后面使用+号实现动态的版本管理
  • 解决冲突更加明确
  • ……

详细区别,可以参考最后的参考资料

Android项目中的Gradle文件

Gradle,Gradle Wrapper,Android Plugin for Gradle区别

在对Android Studio项目中关于gradle文件的介绍之前,先对几个概念进行介绍,在开发中,经常会遇到,尤其是更新Android Studio的时候。

Gradle

与Maven一样,是项目管理工具,上几篇文章对其与Maven都做了简单介绍。

Gradle Wrapper

翻译过来名称是Gradle的包装,其实就是对Gradle进行封装,简化了Gradle本身的安装,部署。不同的开发者,不同的项目,有可能会采用不同版本的Gradle,如果每次切换一个项目,都要手动部署一下对应版本的Gradle,这种麻烦的事肯定不适合程序员,于是就通过Gradle Wrapper实现,就算本地原来没有安装部署Gradle的环境,也可以直接使用。

查看Gradle版本

在项目路径下,通过./gradlew -v可以查看当前项目的Gradle版本,取决于gradle-wrpper.properties中的值。

1
2
3
4
5
6
7
8
9
10
11
➜  StudyTest ./gradlew -v
------------------------------------------------------------
Gradle 4.1
------------------------------------------------------------
Build time: 2017-08-07 14:38:48 UTC
Revision: 941559e020f6c357ebb08d5c67acdb858a3defc2

Groovy: 2.4.11
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_112 (Oracle Corporation 25.112-b16)
OS: Mac OS X 10.13.3 x86_64
Android Plugin for Gradle

Android项目针对Gradle的插件,通过它就可以在Android项目中使用Gradle了。Android官方也对其进行了说明

The Android Studio build system is based on Gradle, and the Android plugin for Gradle adds several features that are specific to building Android apps. Although the Android plugin is typically updated in lock-step with Android Studio, the plugin (and the rest of the Gradle system) can run independent of Android Studio and be updated separately.

大体的意思就是:Android Plugin for Gradle插件添加了构建Android项目的几项功能,虽然其通常与Anroid Studio锁定更新,但是可以独立于Android Studio运行并且单独更新。

Gradle插件版本与Gradle版本

Android Plugin for Gradle版本,Android Studio版本与Gradle版本是有联系的。如果你升级了Android Studio的时候,有可能会收到提示对其进行更新。尽量升级到最新版本,性能更好。目前Plugin和Gradle的版本搭配如下,可以通过Android官网Gradle Plugin介绍进行查询

查看Gradle插件版本

Android Studio 3.0 之前:jcenter仓库

Android Studio 3.0 之后:Google仓库

Android项目中的Gradle

创建一个新的Android项目,可以看到这里有4处关于gradle的配置文件

app/build.gradle

app的gradle配置文件,关于该应用的配置几乎都在这个文件中,平时关注最多的也是这个文件。包含编译的SDK版本,不同编译类型的配置,项目依赖等。

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
// 描述Gradle所引入的插件类型,表示是一个Android Application
apply plugin: 'com.android.application'

// 描述这个是Android module构建过程中的各个参数
android {
// 编译构建工具SDK版本
compileSdkVersion 26
// 当前module的坐标
defaultConfig {
// 在这里定义了项目的包名,之前在Eclipse中,是在AndroidManifest中的,现在改在该文件中。
applicationId "com.guidongyuan.studytest"
// 支持最小SDK版本,则表示编译完成好的app,在SDK 15以下不能运行。
minSdkVersion 15
// 目标SDK版本(建议版本)
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
// 编译类型,可以在此处,对不同编译类型,如release(正式版),debug(测试版)进行配置
buildTypes {
release {
// 是否混淆(false:不混淆)
minifyEnabled false
// 混淆规则的配置文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}

// 项目的所有依赖库
dependencies {
// 本地依赖声明,包含libs文件下的所有jar文件
implementation fileTree(dir: 'libs', include: ['*.jar'])
// 远程依赖声明
implementation 'com.android.support:appcompat-v7:26.1.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
}
gralde/wrapper/gradle-wrapper.properties

定义Gradle Wrapper的一些信息,请求下载的路径,版本号,以及本地存放的位置。

1
2
3
4
5
6
7
8
9
#Mon Apr 30 08:59:50 CST 2018
// 解压gradle-xxx.zip文件后的存放地址,distributionPath是distributionBase的子目录
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
// 下载的gradle-xxx.zip文件的存放地址,zipStorePath是zipStoreBase的子目录
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
// gradle下载的路径以及版本号
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip

GRADLE_USER_HOME:用户的gradle目录,mac下的路径如下/Users/guidongyuan/.gradle,window下的路径为C:\User\用户名\.gradle

另外,Android Studio默认也带有gradle,路径为

Studio.app/Contents/gradle/gradle-4.1```。
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
54
55
56
57
58
59
60
61
62
63
64

###### 离线导入gradle wrapper

以前开始接触Android Studio最常遇到的问题,导入项目卡在下载Gradle Wrapper,解决办法:

* 修改项目的gralde-wrapper版本为本地已经有的。

* 自行在[Gradle Wrapper官网](https://services.gradle.org/distributions/)下载放进去,先运行一下,然后会生成指定目录,直接放在该路径就可以了。

下图为把gradle-wrapper改为4.7生成的文件夹,直接把下载好的文件放到4cret……文件夹内(根据distribution url路径字符串计算md5值得来的)就可以了。

![](http://guidongyuan.cn/images/2018-05-01-15251360478203.jpg)

###### 使用本地Gradle Wrapper

![](http://guidongyuan.cn/images/2018-05-01-15251363375403.jpg)

**Project-level settings**
- Use Default gradle wrapper
如果使用Use Default gradle wrapper则会使用gradl-wrapper.properties中定义的版本。
- Use local gradle distribution
使用上面的配置,如果导入不同的项目可能会导入不同的grald版本,本地没有对应的版本,则需要通过网络下载。所以,在实际开发中,一般勾选Use local gradle distribution使用本地的,一般会选择Android Studio中自带的gralde版本,如`/Applications/Android Studio.app/Contents/gradle/gradle-4.4`。

**Global Gradle settings**

- Offline work
离线模式,如果gralde都已经下载到本地,尤其是勾选Use local gradle distributio,选中它可以提高编译速度。

- Service directory path
设置依赖库下载的保存地址,测试了一下,发现,加入新的第三方库或者使用Use Default gradle wrapper选择然后修改gradle版本,会保存到该路径下。
该路径可以理解为,本地gradle的总仓库,会缓存所有的内容。


##### build.gradle

整个项目的gradle配置文件,定义依赖仓库的地址

```groovy
buildscript {
// 仓库
repositories {
google()
jcenter()
}
// 依赖库
dependencies {
// 声明gradle插件的版本
classpath 'com.android.tools.build:gradle:3.0.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}

allprojects {
repositories {
google()
jcenter()
}
}

// gradle的一个task,执行clean的时候,会删除编译路径下的文件
task clean(type: Delete) {
delete rootProject.buildDir
}

修改gradle插件的版本的时候,会保存到Android Studio应用内的m2repository仓库中。

gradle.properties

在该文件夹定义设计gradle相关的一些属性。在使用gradle的task时候,经常会在此定义一些全局变量,然后直接去调用。

settings.gradle

声明整个项目中需要gralde的module

1
include ':app'

参考资料

Maven与Gradle对比

Android

公众号:亦袁非猿

欢迎关注,交流学习