Gradle简介

gradle学习资源

官网doc: gradle官网doc
书:Android gradle权威指南
电子资源:gradle android插件用户指南
视频资源:慕课网,gradle自动化项目构建技术精讲

gradle简介

Gradle是一个优秀的构建系统和构建工具,它允许通过插件创建自定义的构建逻辑,、
优点:

  1. 采用了Domain Specific Language(DSL语言)来描述和控制构建逻辑。
  2. 构建文件基于Groovy,并且允许通过混合声明DSL元素和使用代码来控制DSL元素以控制自定义的构建逻辑。
  3. 支持Maven或者Ivy的依赖管理。
  4. 非常灵活。允许使用最好的实现,但是不会强制实现的方式。
  5. 插件可以提供自己的DSL和API以供构建文件使用。
  6. 良好的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 nameprintlnmynameis 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扩展:

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值