概述
gradle学习资源
官网doc: gradle官网doc
书:Android gradle权威指南
电子资源:gradle android插件用户指南
视频资源:慕课网,gradle自动化项目构建技术精讲
gradle简介
Gradle是一个优秀的构建系统和构建工具,它允许通过插件创建自定义的构建逻辑,、
优点:
- 采用了Domain Specific Language(DSL语言)来描述和控制构建逻辑。
- 构建文件基于Groovy,并且允许通过混合声明DSL元素和使用代码来控制DSL元素以控制自定义的构建逻辑。
- 支持Maven或者Ivy的依赖管理。
- 非常灵活。允许使用最好的实现,但是不会强制实现的方式。
- 插件可以提供自己的DSL和API以供构建文件使用。
- 良好的API工具供IDE集成。
注意:学习gradle需要有好的Java基础和groovy基础。
project:
gradle中最重要的概念,project类代表了你的项目,在gradle中,每一个项目都是一个project,gradle中已目录树的形式记录项目,根目录有rootproject,每个项目的子项目又是一个project
settings.gradle:
对应gradle中的settings类,Settings.gradle文件就是对settings类进行配置,gradle中多工程通过工程树表示,Android studio中project和module概念一样,根工程相当于project,子工程相当于module,settings类方法不多,主要了解include,就可以了,
include方法:将子项目引入到项目,配置整个项目包含的子项目。只有引入构建子项目才能被包含进去。
include 'app' //在同级目录下的子项目直接指定,不用指定位置
include 'song' //不在同级目录需要指定,子项目的位置。
project('song').projectDir = new File(rootDir,'tian/song')
//指定不同位置的项目, rootDir:根项目所在位置。
build.gradle
#
groovy基础:
1:groovy是基于jvm的一种动态语言,语法和Java非常相似,完全兼容Java,又增加了很多动态类型和
灵活特性,eg:支持闭包,DSL,
注意:groovy中分号结束不是必须的,可以省略。
变量定义:
直接指定类型,与Java相同 double x = 3.14
推断变量类型 ,使用def关键字 def x = 3.14 //自动推断出x 为double
2:字符串
单引号和双引号都可以定义字符串变量,不同的是单引号标记纯粹的字符串,双引号可以对字符里的表达式做运算
eg: task hello {
doLast {
def name = ‘tian’
println ‘my name is
name′println“mynameis
n
a
m
e
′
p
r
i
n
t
l
n
“
m
y
n
a
m
e
i
s
{name}”
}
}
输出为:my name is
namemynameistian使用:嵌套规则,一个
n
a
m
e
m
y
n
a
m
e
i
s
t
i
a
n
使
用
:
嵌
套
规
则
,
一
个
符号后紧跟一个{},{}里面放表达式,如果表达式是一个变量可以省略{}.
使用三引号,‘’‘ ’‘’, 输出规定的内容,里面是什么内容就输出什么内容。
3:集合
groovy完全兼容了Java集合,并进行了扩展,有list, map, set, queue,
3.1:list
eg:
task hello {
doLast {
def numList = [1,2,3,4,5] //定义使用[]
println numList.getClass().name //获得类的类型,ArrayList
println numList[1] //获取第一个元素
println numList[-1] //获取倒数第一个元素
println numList[1..3] //获取1到3的
}
}
遍历:list提供了闭包的each方法
eg: numList.each {
println it //it就是正在迭代的元素,
}
3.2:Map:
def map = ['width':2014,'height':768]
println map['width'] //key访问。
println map.width
遍历:也有each方法,不同的是迭代元素是一个Map.Entry实例。
map.each {
println "key: ${it.key} , value : ${it.value}"
}
4:方法
4.1:省略()。Java方法调用需要method(parm1, parm2),在groovy中()是可以省略的,
eg: task hello {
doLast {
addTest(1,2)
addTest 1, 2
}
}
def addTest(int a, int b) {
println a + b
}
4.2:可以省略return, 没有return时groovy会把方法执行的最后一句代码作为返回值。
5:逻辑控制:
5.1:switch/case与Java不同点,可以传入任意类型,来匹配 eg:
switch (x) {
case “foo”
println x
break
case ‘bar’
println x
break
case [2,4,5, ‘in’]: //列表
break
case 12..30: //范围
break
case Integer:
println x
break //类型
}
5.2:for循环
范围循环
eg: for( i in 0..9) { println i} //0..9 为范围定义
list循环
eg: for( i in [1,2,3,4]) { println i} //循环list
map循环
eg : for(i in ["tian": 1, "song":2,"tao",3]) {
println i.key + i.value;
//这里的i得到的是map中的Entry, 包含key和value
}
6:闭包: 就是一个代码块 {parms -> method}
定义:{String s -> println( “tian s”)}
调用: 将闭包赋值给变量,变量就相当于闭包
def clouser = { println(“song”)
执行: clouser.call() //调用闭包的call()
clouser() //直接执行,调用与Java方法调用一致。
def song = {String s -> println(
s”)} 调用: 将闭包赋值给变量,变量就相当于闭包 def clouser = { println(“song”) 执行: clouser.call() //调用闭包的call() clouser() //直接执行,调用与Java方法调用一致。 def song = {String s -> println(
s)
song.call(“tian”)
song(“tian”)
当闭包只有一个参数时,可以使用闭包的默认参数it,
eg: def song = { println("$it") //闭包隐式参数。
song("tian")
返回值:与方法的返回类似,闭包必有返回值, 没有return,则返回为Null
eg: def song = {String s -> return "hello $s"}
def result = song("tian")
println result
7:闭包中的this, owner, delegate
this:代表闭包定义处的类
owner: 代表闭包定义处的类或者对象,
delegate:代表任意对象,默认与owner一致。
gradle:
1:生命周期:
initiallzation初始化阶段:解析整个工程中所有的project,构建所有project对应的project对象。
configuration配置阶段:解析所有project对象中的task,构建好所有task的拓扑图
Execution执行阶段:执行具体的task,以及其依赖的task。
2:gradle执行流程函数
this.beforeEvaluate{} //开始配置前调用
this.afterEvaluate{} //配置完成后调用
this.gradle.buildFinish{} //task执行完后调用
3:gradle project:
gradle生命周期API
this.beforeEvaluate{} //开始配置前调用
this.afterEvaluate{} //配置完成后调用
this.gradle.buildFinish{} //task执行完后调用
project相关API
1:获得全部的project, this.getAllProjects(),
在那个模块或者整个项目根项目调用该函数,就是获得的模块或者跟项目所对应的project
eg: this.getAllProjects().eachWith
2:获得当前project下所有子project, getSubprojects(),
3:getParent(), 获取项目的父project
4:getRootProject(), 获得项目的根项目的project
对子project进行操作:
1:Project project(String path, Closure configureCloure) :
path:子项目的路径,,相对于根目录,直接用module的名字即可, eg: “app”
closure:闭包参数,对子项目的配置
eg: 可以在父项目中对子项目完全配置,相当于子项目中的build.gradle
project(“app”) {Project project ->
println project.name + “tiansongtao” //项目名称
apply plugin:’com.android.application’ //项目类型
group ‘com.tian’ //项目所属组
version ‘1.0’ //项目版本
dependencies {} //项目依赖配合
android {} //Android配置
}
2:allprojects(Closure closure) 、、参数是一个闭包
这个API可以配置项目中的所有project的参数,
3:subprojects(closure closure) // 参数是一个闭包
配置自工程,不包含当前的项目,只包含项目下的子项目
task相关API
属相相关API
属性就是项目的参数,类似 version minSdkVersion,
gradle中project是一个类,如果我们还想原来一样定义version 1,这样很不好,
1:使用groovy中的变量定义
def mVersion = 1
在配置时使用 version mVersion
2:定义扩展属性, 使用ext{}闭包, 扩展块,
ext{
version = 1
}
使用: version this.version
注意:因为gradle中的project是继承关系,更具Java继承关系,父类定义的属性子类是可以直接使用的,所以在这里ext闭包定义的属性,在项目的子项目中,配置参数可以直接使用。
2:我们可以将所有的属性定义到一个gradle文件中,再在rootproject中引入,这样更好的配置项目
eg: gradle 文件中只用ext就可以, 用map定义,
ext { android = [compileSdkVersion : 25,
buildToolsVersion : '25.0.0',] //android 配置参数
java = ['javaVersion': JavaVersion.VERSION_1_7] //Java配置参数 }
rootproject使用:
apply form : this.file("tian.gradle")
使用参数: rootproject.ext.android.compileSdkVersion
file相关API
路径获取API:
getRootDir() //根目录路径 getRootDir().absolutePath
getBuildDir() //获得build文件的目录
getProjectDir() //获取当前project的目录
文件操作API:
1:复制: copy{} 闭包,
copy{
from file(“tian.txt”) //拷贝那个文件
to getRootProject().getBuildDir() //拷贝到的位置。
}
2:文件树的遍历:遍历文件夹下的所有文件
fileTree(“app/src/main/”) { FileTree fileTree ->
fileTree.visit {FileTreeElement fileTreeElement ->
println “file name :” + fileTreeElement.name
}
}
其他API
依赖相关API:buildscript
buildscript {scriptHandler scriptHandler -> //配置多个依赖
//配置工程仓库地址
scriptHandler.repositories { RepositoryHandler repositoryHandler ->
repositoryHandler.google()
repositoryHandler.jcenter() {
name “patter”
url ‘http://localhost:8081:/nexus’ //jcenter地址
credentials { //配置使用的账号密码
username = ‘admin’
password = ‘admin123’
}
}
}
//配置工程插件地址。这个插件是gradle的插件,编译时的依赖,
//并不是项目开发的依赖,
scriptHandler.dependencies {}
}
//为应用程序添加依赖 project中的dependencies
dependencies {
compile fileTree(include : [*.jar], dir:'libs') //利用fileTree遍历文件夹,添加依赖,
compile 'com.android.support:support-v4:27.1.1' //直接添加依赖
compile project(':module-aiui') //添加工程源码依赖,
/**
* 引入依赖的方式 compile / provided:
*compile:的引入最终会打包进我们的apk
*provided:占位编译: 我们在编译时使用这个依赖资源,但我们打包时不会打进我们的apk
**/
}
//添加依赖出现的问题:
1:依赖冲突: 重复依赖,多个依赖中包含同一个依赖包
解除冲突:
compile('com.android.support:support-v4:27.1.1') {
exclude module :'support-v4' //排除依赖,
}
2:传递依赖:
compile('com.android.support:support-v4:27.1.1') {
transitive false //取消传递依赖,这里我们的工程只能使用support-v4,不能使用support-v4的依赖jar,
}
外部命令执行 : 执行bash
eg:
task(name:’apkcopy’) {
doLast {
def sourcePath = this.buildDir.path + ‘/outputs/apk’
def outputPath = /home/tian/’
def command “mv -f
sourcePath
s
o
u
r
c
e
P
a
t
h
{outputPath}” //shell 命令
exec { //执行
try {
executable ‘bash’ //这里是固定的
args ‘-C’, command //这里也是固定的,只有command不同。
} catch (GradleException e){
println “this command error ${e.toString()}”
}
}
}
}
task:
task定义及配置
1:task hellotask(group:’tian’, description:’task study’) { //task 名字, task方法,创建task,
setGroup(‘tian’) //对task进行分组方便查找
setDescription(‘task study’) //该task的描述
println ’ I am hellotask’
}
2:使用task的管理类,taskContainer创建task,使用的方法为tasks
this.tasks.create(name :’helloTask2’) {
println “I am helloTask 2”
}
task的执行详解
task和gradle中的配置一样,配置代码都会在gradle的配置环节运行,但task有doFirst和doLast方法,这两个方法可以让程序在gradle执行阶段运行。
1:doFirst{} 是一个方法,闭包作为参数,这个方法可以多次调用
eg:
task helloTask(group:’tian’, description:’study task’) {
println “I am hello task”
doFirst {
println ” I am hellotask dofirst”
}
doLast {
println ‘I am hellotask dolast’
}
}
//在外部调用
helloTask.doFirst {
print ‘nihao’
}
2:doLast{} 和doFirst一样,一个是执行在gradle执行前,dolast在执行后。
task的依赖和执行顺序
执行顺序:task执行顺序主要有三种影响,
1:dependsOn强依赖;在task的配置中使用dependsOn添加依赖,这样执行task时,会先执行依赖的task
eg:
task taskx(group:’tian’){
doLast{ println ‘taskx’ }
}
task tasky(group:’tian’){
doLast { println “tasky” }
}
//添加多个依赖,使用集合[]
task taskz(group:’tian’, dependsOn:[taskx, tasky]){
doLast { println ‘taskz’ }
}
taskz.dependsOn(taskx, tasky) //在外面定义依赖
2:通过task输入输出指定
通过input与output指定一个task的输出是另一个task的输入。
3:通过API指定执行顺序
task类型
task挂接到构建生命周期
task实战
SourceSet类:指定项目从哪里加载代码文件和依赖等,
eg:
this.android.sourceSets {
main {
res.srcDirs =[‘src/main/res] //为Android指定资源路径
}
}
Plugin类自定义Plugin
Android插件对gradle扩展:
最后
以上就是奋斗小馒头为你收集整理的Gradle简介的全部内容,希望文章能够帮你解决Gradle简介所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复