目录
概念
Gradle是一个项目自动化构建工具,用过Ant和Maven构建工具的人都知道,它们都是通过xml形式构建脚本,而Gradle通过Groovy语言封装成方法式的配置方式构建脚本;
安装
1、安装JDK
2、下载Gradle并安装
3、配置环境变量 java -version 查看JDK版本, gradle -v 查看gradle版本;
以上安装都很简单
如果你用的开发工具是Android Studio 只需要安装JDK就可以了,Android Studio 是自带安装gradle的。
Groovy
这里想先简单介绍一下Groovy的概念,Groovy是什么?Groovy是用于Java虚拟机的一种敏捷的动态语言(DSL),面向对象的一种编程语言,同时又是一种脚本语言,代码书写规则简单,包含闭包和一般动态语言的其他特性;
Groovy与Java
- 完全兼容Java的语法;
- 方法和类都是默认public的;
- 编译器会自动给属性添加get/set方法;
- 属性可以通过直接用点号获取,类似于java的静态变量;
- 最后一个表达式的值是返回值;
- 不会有空指针错误;
- 分号并不是必须的;
特性
- 任何地方可以执行assert断言语句;
- 类型不必明确定义,根据赋值类型定义属性类型;
调用方法时可以不写括号;
字符串的三种表达式:”string” ‘string’ ”’string”’
三种方式的区别:
'':单纯的字符串;
"":可以插入变量,比如:
def a = world
"hello ${a} !!!"
'''''':字符串可以换行,比如:
'''hello
world
!!!'''
集合
list 相当于java中的 Arraylist
def list = ['java','gradle','groovy']
list << 'c#' //追加到list中
调用方法:list[0]
map 相当于java的 LinkHashMap
def map = ['javaver':1.8,'gradlever':4.1]
map.groovy=2.4.15 // 追加元素
调用方法:map.javaver
- 闭包(闭包简单的理解就是 方法内部定义内部方法,而这个内部方法提高给外部使用)
def m1 = {
p > print p
}
def m2 = {
print 'world'
}
def m3(Closure closure){
closure('hello')
}
def m4(Closure closure){
closure()
}
调用:
m3(m1)
m4(m2)
构建脚本
构建块
gradle构建中的有两个基本的概念:项目(project)、任务(task),每个构建块至少包含一个project、project中包含一个或多个task。在多项目构建中,一个项目可以依赖于其他项目,任务也可以形成一个依赖关系图来确保他们的执行顺序。
解读:Project1中TaskA依赖于TaskB,TaskB依赖于TaskC,Project2中TaskD依赖于TaskE,TaskE依赖于TaskF,而Project1依赖于Project2,所以构建顺序应该是TaskF-E-D-C-B-A;
- 项目(Project)
概念:一个项目代表一个正在构建的组件(如:jar、aar等),构建启动后,gradle会基于build.gradle实例化一个org.gradle.api.Project对象,并且能够通过project变量使其隐式可用,build.gradle中编写的变量、方法等脚本都会在这个project对象中运行;
什么是隐式调用?举个栗子:
在build.gradle中
group 'com.ailian.test' 这个就是隐式调用
原版应该是:
project.group = 'com.ailian.test'
属性:
group 组
name 名称,一个组不能重名
version 版本号,构建出project的版本号
通过以上三个属性可以唯一确定一个对象;
如:依赖gson的写法:
compile 'com.google.code.gson:gson:2.8.4'
compile group:'com.google.code.gson',name:'gson',version:'2.8.4'
group : com.google.code.gson
name : gson
verson : 2.8.4
方法:
apply 运用插件
dependencies 依赖
reprositories 仓库
task 任务
属性的其他配置方式:ext、gradle.properties(键值对方式定义属性)
- 任务(task)
概念:任务对应org.gradle.api.Task。主要包括任务动作和任务依赖。任务动作定义了一个最小的工作单元,可以定义依赖于其他任务、动作执行顺序和执行条件。
方法:
dependsOn 声明任务依赖
doFirst 任务列表最前面执行的任务
doLast或<< 任务列表最后面执行的任务
一个任务列表可以执行多次doFirst和doLast方法
构建生命周期
- 初始化
初始化需要参与到构建中的项目 - 配置
生成task的依赖顺序和执行顺序 - 执行
执行动作代码
依赖管理
几乎所有基于JVM的软件项目都需要依赖外部类库来重用现有的功能,自动化的依赖管理可以明确依赖的版本,可以解决因传递性依赖带来的版本冲突。
常用仓库
公共仓库:可以上传依赖包和下载依赖包
mavenCentral :search.maven.org
jcenter :https://jcenter.bintray.com/
google
私有仓库:mavenLocal 本地已有的依赖包
自定义仓库:公司内部的仓库
如:build.gradle中的配置
repositories{
maven{
url "https://oss.sonatype.org/content/repositories/snapshots"//自定义仓库地址
}
mavenLocal()
mavenCentral()
jcenter()
}
根据上面的配置顺序会依次从上面的仓库查找依赖包,找到为止,找不到则报错
依赖的传递性
B依赖A,C依赖B,则C依赖A
正因为有版本的传递性,才会有依赖冲突的问题
比如:
B依赖A:1.2版本
C依赖A:1.3版本
D依赖B和C
根据依赖的传递性,D依赖A,这时A有两个版本1.2和1.3,这时候就出现了冲突
依赖传递性从另一个角度看可以尽量减少已有的依赖避免依赖版本冲突的问题;
比如:A模块依赖了Gson包,主工程B依赖A模块,主工程B就不需要单独依赖Gson包了。
解决版本冲突的方法:
1、排除传递性依赖
dependencies{
compile('com.jakewharton.rxbinding2:rxbinding-design:2.0.0'){
exclude group: 'com.android.support'
}
}
编译rxbinding-design时排除依赖包“com.android.support”
2、强制指定一个版本
configurations.all{
resolutionStrategy{
force 'com.android.support:appcompat-v7:26.0.0'
}
}
项目中所有使用com.android.support:appcompat-v7的包都强制使用26.0.0的版本
多项目构建
在真实的项目开发中,包层次和类关系都比较复杂,所以这时需要将代码拆分模块,拆分出的模块可以通过gradle的依赖管理构建出一个完整的项目;
一个可运行项目必然会会有一个root proejct,其他Moudle为Subprojects,每个Moudle包括root project都有一个build.gradle配置文件。
rootproject的build.gradle可以定义所有subprojects的共同配置项:
rootproject的build.gradle:
allprojects{//所有subprojects的build.gradle公共定义方法
repositories {//定义所有subprojects都使用这个公共仓库
jcenter()
maven { url 'https://jitpack.io' }
}
}
没有subproject也可以定义自己的配置;
构建项目的发布
俗话说,独乐乐不如众乐乐,我们写了好的工具,自然需要分享,我们自己构建处理的项目(比如:jar包)可以通过gradle自动发布到公共仓库或者其他私服仓库,共享给其他开发者使用;
gradle没有自己的仓库,所以都是使用maven仓库;
如果需要发布到远程公共仓库,需要注册对应的仓库账号,以及发布后需要审核通过后才能供其他开发者使用,gradle配置发布的脚步:
apply plugin:'maven-publish'
publishing{
publications{
huoPublish(MavenPublication){
from components.java
}
}
repositories{
maven{
name ""//项目名称
url ""//发布地址
}
}
}
总结
要效率的开发出高质量的项目,需要学会使用好各种开发工具,更要懂得这些高效开发工具的工作原理与使用方法,对于我们开发项目是有好处的,这里只是接受gradle的基础部分,gradle还有很多其他更高阶的使用,有兴趣的同学可以更深入的研究;