Gradle脚本基础全攻略,Android开发教程

在初始化阶段如果我们在根路径下直接指明settings.gradle文件和相关配置则构建初始化就会直接按照我们的设置去构建项目,如果我们没指明settings.gradle文件则Gradle会以一定的规则去寻找settings.gradle文件,然后依据寻找结果的不同去决定如何构建项目。

【工匠若水 http://blog.csdn.net/yanbober 转载请注明出处。点我开始Android技术交流

3 Gradle构建基础

================

通过上一章可以知道,每一个Gradle构建都是由一个或多个project构成,每一个project都是由一个或多个tasks构成,每个task的实质其实是一些更加细化的构建(譬如编译class、创建jar文件等)。

任务task基础:

如下例子我们先来直观感受一下task的概念,具体细节后面会探讨:

//创建一个名为build.gradle的文件

task hello {

doLast {

println ‘Hello world!’

}

}

//这是快捷写法,用<<替换doLast,后面解释

task hl << {

println ‘Hello world!’

}

//创建upper的task,使用Groovy语言编写

task upper << {

String someString = ‘mY_nAmE’

println "Original: " + someString

println "Upper case: " + someString.toUpperCase()

}

通过如下命令运行构建上面名为hello的task,具体如下:

xxx@XXX:~/$ gradle hello

:hello

Hello world!

BUILD SUCCESSFUL

Total time: 1.037 secs

可以看见,gradle命令会在当前目录中查找一个叫build.gradle的构建脚本文件,这个构建脚本定义了一个叫做hello的独立task,并且添加了一个action,我们执行了这个task就得到了想要的结果。

在这里再多嘴一句,我们看下task有无action的区别,如下:

//有Action的task

task actionTask << {

println ‘I am actionTask’

}

//无Action的task

task noActionTask {

println ‘I am noActionTask’

}

一定要记住,在上面这个例子中如果task没有加<<则这个任务在脚本初始化initialization阶段(即无论执行啥task都被执行,具体参见上一章的第一个例子)被执行,如果加了<<则在gradle actionTask后才执行。因为没有加<<则闭包在task函数返回前会执行,而加了<<则变成调用actionTask.doLast(),所以会等到gradle actionTask时执行。

任务task依赖:

我们通过上面task基础感受的例子可以发现,一个build.gradle文件中定义多个task互相没有关系,决定执行的是我们gradle命令后面跟的task名字;那我们要是让他们之间有依赖关系咋办呢?如下:

task taskX(dependsOn: ‘taskY’) << {

println ‘taskX’

}

task taskY << {

println ‘taskY’

}

运行结果如下:

xxx@XXX:~/$ gradle taskX

:taskY

taskY

:taskX

taskX

BUILD SUCCESSFUL

Total time: 1.039 secs

动态任务task:

我们还可以在Gradle中使用Groovy来创建动态task,如下:

4.times { counter ->

task “task$counter” << {

println “I’m task number $counter”

}

}

运行结果如下:

xxx@XXX:~/$ gradle task1

:task1

I’m task number 1

BUILD SUCCESSFUL

Total time: 1.397 secs

使用已存在任务task:

我们除过在上面定义任务task时指明依赖以外还可以通过API为任务加入一个依赖,如下:

4.times { counter ->

task “task$counter” << {

println “I’m task number $counter”

}

}

task0.dependsOn task2, task3

运行结果如下:

xxx@XXX:~/$ gradle task0

:task0

I’m task number 2

I’m task number 3

I’m task number 0

BUILD SUCCESSFUL

Total time: 1.397 secs

或者我们还可以通过API为任务加入一些新行为,如下:

task hello << {

println ‘Hello Earth’

}

hello.doFirst {

println ‘Hello Venus’

}

hello.doLast {

println ‘Hello Mars’

}

hello << {

println ‘Hello Jupiter’

}

运行结果如下:

xxx@XXX:~/$ gradle hello

:hello

Hello Venus

Hello Earth

Hello Mars

Hello Jupiter

BUILD SUCCESSFUL

Total time: 1.397 secs

可以发现,doFirst和doLast可以被执行多次,<<操作符实质就是doLast。

任务task短标记:

我们可以通过美元符将一个task作为另一个task的属性,如下:

task hello << {

println ‘Hello world!’

}

hello.doLast {

println “Greetings from the $hello.name task.”

}

执行结果如下:

xxx@XXX:~/$ gradle hello

:hello

Hello world!

Greetings from the hello task.

BUILD SUCCESSFUL

Total time: 1.397 secs

可以看见,上面脚本中使用的name其实是任务的默认属性, 代表当前任务的名称。

自定义任务task属性:

我们还可以给任务task加入自定义的属性,如下例子:

task myTask {

ext.myProperty = “myValue”

}

task printTaskProperties << {

println myTask.myProperty

}

执行结果如下:

xxx@XXX:~/$ gradle printTaskProperties

:printTaskProperties

myValue

BUILD SUCCESSFUL

Total time: 1.397 secs

定义默认任务task:

Gradle允许在脚本中定义一个或多个默认任务,如下:

defaultTasks ‘clean’, ‘run’

task clean << {

println ‘Default Cleaning!’

}

task run << {

println ‘Default Running!’

}

task other << {

println “I’m not a default task!”

}

执行结果如下:

xxx@XXX:~/$ gradle

:clean,run

Default Cleaning!

Default Running!

BUILD SUCCESSFUL

Total time: 1.397 secs

【工匠若水 http://blog.csdn.net/yanbober 转载请注明出处。点我开始Android技术交流

4 Gradle依赖管理基础

==================

大多数项目都不是完全独立的,它们需要依赖其他项目进行编译等,Gradle允许你告诉它你项目的依赖关系,以便找到这些依赖关系,并在你的构建中维护这些依赖关系,依赖关系可能需要从远程的Maven等仓库中下载,也可能是在本地文件系统中,或者是通过多项目构建另一个构建,我们称这个过程为依赖解析。

Gradle依赖声明:

关于依赖声明不解释,直接给个例子,如下:

apply plugin: ‘java’

repositories {

mavenCentral()

}

dependencies {

compile group: ‘org.hibernate’, name: ‘hibernate-core’, version: ‘3.6.7.Final’

testCompile group: ‘junit’, name: ‘junit’, version: ‘4.+’

}

Gradle依赖配置:

在Gradle中依赖可以组合成configurations(配置),一个配置简单地说就是一系列的依赖,通俗说也就是依赖配置;我们可以使用它们声明项目的外部依赖,也可以被用来声明项目的发布。下面我们给出几种Java插件中常见的配置,如下:

  • compile

用来编译项目源代码的依赖;

  • runtime

在运行时被生成的类需要的依赖,默认项,包含编译时的依赖;

  • testCompile

编译测试代码依赖,默认项,包含生成的类运行所需的依赖和编译源代码的依赖;

  • testRuntime

运行测试所需要的依赖,默认项,包含上面三个依赖;

各种各样的插件支持许多标准的配置,我们还可以定义自己的配置。

Gradle外部依赖:

我们可以用Gradle声明许多种依赖,其中有一种是外部依赖(external dependency),它是在当前构建之外的一种依赖,一般存放在远程(譬如Maven)或本地的仓库里。如下是一个外部依赖的例子:

dependencies {

compile group: ‘org.hibernate’, name: ‘hibernate-core’, version: ‘3.6.7.Final’

}

可以看见,引用一个外部依赖需要用到group、name、version属性。上面的写法还有一种简写,如下规则:

group:name:version

这是一个简写的例子:

dependencies {

compile ‘org.hibernate:hibernate-core:3.6.7.Final’

}

Gradle仓库:

有了上面的外部依赖,你指定会想Gradle是咋找到那些外部依赖文件的。其实Gradle会在一个仓库(repository)里找这些依赖文件,仓库其实就是很多依赖文件的集合服务器, 他们通过group、name、version进行归类存储,好在Gradle可以解析好几种不同的仓库形式(譬如Maven等),但是Gradle默认不提前定义任何仓库,我们必须手动在使用外部依赖之前定义自己的仓库。

下面是一个使用MavenCentral仓库的例子:

repositories {

mavenCentral()

}

这是一个使用远程Maven仓库的例子:

repositories {

maven {

url “http://repo.mycompany.com/maven2”

}

}

这是一个使用本地文件系统里库的例子:

repositories {

ivy {

// URL can refer to a local directory

url “…/local-repo”

}

}

当然了,一个项目可以有好几个库,Gradle会根据依赖定义的顺序在各个库里寻找它们,在第一个库里找到了就不会再在第二个库里找它了,否则在第二个库找。

Gradle发布artifacts:

依赖配置也可以用来发布文件,我们可以通过在uploadArchives任务里加入仓库来完成。下面是一个发布到Maven 库的例子,Gradle将生成和上传pom.xml,如下:

apply plugin: ‘maven’

uploadArchives {

repositories {

mavenDeployer {

repository(url: “file://localhost/tmp/myRepo/”)

}

}

}

【工匠若水 http://blog.csdn.net/yanbober 转载请注明出处。点我开始Android技术交流

5 Gradle命令

==============

多任务调用命令:

gradle task1 task2 […]

排除任务命令:

gradle -x task1 task2 […]

失败后继续执行构建命令:

只要有任务调用失败Gradle默认就会中断执行,我们可以使用–continue选项在一次调用中不中断执行,然后发现所有失败原因。

简化任务名命令:

当我们调用某个任务时如果名字太长我们可以采用简化操作,但是必须保证可以唯一区分出该任务的字符,譬如:

//简写

gradle -x t1

//替换

gradle -x task1

选择执行构建命令:

调用gradle命令默认会构建当前目录下的build.gradle文件,我们可以使用-b参数选择其他目录的构建文件且当使用此参数时settings.gradle将不会生效。如下:

//选择文件构建subdir/myproject.gradle

task hello << {

println “using build file ‘ b u i l d F i l e . n a m e ′ i n ′ buildFile.name' in ' buildFile.nameinbuildFile.parentFile.name’.”

}

执行过程:

xxx@XXX:~/$ gradle -b subdir/myproject.gradle hello

:hello

using build file ‘myproject.gradle’ in ‘subdir’.

BUILD SUCCESSFUL

Total time: 1.397 secs

此外我们还可以使用-p参数来指定构建的目录,譬如在多项目构建中可以用-p替代-b参数。如下执行过程:

xxx@XXX:~/$ gradle -p subdir hello

:hello

using build file ‘build.gradle’ in ‘subdir’.

BUILD SUCCESSFUL

Total time: 1.397 secs

获取构建信息:

  • gradle projects命令:列出子项目名称列表。

  • gradle tasks命令:列出项目中所有任务。

  • gradle help –task someTask命令:可以显示指定任务的详细信息。

  • gradle dependencies命令:列出项目的依赖列表,所有依赖会根据任务区分,以树型结构展示。

【工匠若水 http://blog.csdn.net/yanbober 转载请注明出处。点我开始Android技术交流

6 编写Gradle脚本

================

Gradle是以Groovy语言为基础,基于DSL语法的自动化构建工具,一个构建脚本能够包含任何Groovy语言元素,每个脚本都是UTF-8编码的文件。

6-1 Project对象API


前面我们说过,Gradle在构建脚本中定义了一个project,对于构建脚本中每个project其实Gradle都创建了一个 Project类型的对象来关联,当构建脚本执行时它会去配置所关联的Project对象;构建脚本中每个被调用的方法和属性都委托给了当前Project对象。

如下我们看一个使用Project属性的例子:

println name

println project.name

上面两个println语句的输出是一样的;由于name属性没有在当前脚本中定义,所以可以像第一个那样使用自动委托 ,通常我们使用第二中写法。

Project对象提供了一些标准的属性,我们可以在构建脚本中很方便的使用他们,如下:

| Name | Type | Default Value |

| — | — | — |

| project | Project | Project实例对象 |

| name | String | 项目目录的名称 |

| path | String | 项目的绝对路径 |

| description | String | 项目描述 |

| projectDir | File | 包含构建脚本的目录 |

| build | File | projectDir/build |

| group | Object | 未具体说明 |

| version | Object | 未具体说明 |

| ant | AntBuilder | Ant实例对象 |

具体关于Project的方法详情参阅Project的API文档。这里我们给出Project的apply方法的一个例子,如下:

//加载一个gradle文件

apply from: rootProject.getRootDir().getAbsolutePath() + “/common.gradle”

6-2 Script对象API


当Gradle执行一个脚本时它会将这个脚本编译为实现了Script的类(在上篇博客《Groovy脚本基础全攻略》Groovy的本质编译class代码那块有介绍),也就是说所有的属性和方法都是在Script的接口中声明。

6-3 Gradle对象API


关于Gradle对象的详细属性和API介绍点我即可。这里直接给出一个使用Gradle对象的例子,如下:

这里写图片描述

6-4 Gradle变量声明


在Gradle脚本中有两种类型的变量可以声明,如下:

  • 局部变量

  • 扩展变量

局部变量使用关键字def声明,它只在声明的地方可见,如下:

def dest = “dest”

task copy(type: Copy) {

form “source”

into dest

}

在Gradle中所有被增强的对象可以拥有自定义属性(譬如projects、tasks、source sets等),使用ext扩展块可以一次添加多个属性。如下:

apply plugin: “java”

ext {

springVersion = “3.1.0.RELEASE”

emailNotification = “build@master.org”

}

sourceSets.all { ext.purpose = null }

sourceSets {

main {

purpose = “production”

}

test {

purpose = “test”

}

plugin {

purpose = “production”

}

}

task printProperties << {

println springVersion

println emailNotification

sourceSets.matching { it.purpose == “production” }.each { println it.name}

}

上面我们用一个ext扩展块向Project对象添加两个扩展属性,当这些扩展属性被添加后,它们就像预定义的属性一样可以被读写。

6-5 Gradle中Groovy使用


这个没啥说的,具体可以参考《Groovy脚本基础全攻略》这篇博客,里面有详细介绍。我们这里粗略总结回忆一下即可:

  • Groovy会自动将一个属性的引用转换为相应的getter/setter方法。

  • Groovy调用方法时圆括号可有可无。

  • Groovy为List和Map集合提供了一些操作捷径,譬如apply plugin:’java’中的plugin:’java’其实就是Groovy中的Map,apply是一个方法,省略了括弧而已。

哎呀,详细的还是去看前一篇博客吧。

【工匠若水 http://blog.csdn.net/yanbober 转载请注明出处。点我开始Android技术交流

7 Gradle文件操作基础

==================

实际使用Gradle过程中大多数时候需要操作文件,好在Gradle给我们提供了一些API来快捷处理。

定位文件:

我们可以使用Project.file()方法来定位一个文件获取File对象(详情参考Project的API),如下:

//相对路径

File configFile = file(‘src/config.xml’)

//绝对路径

File configFile = file(configFile.absolutePath)

//项目路径的文件对象

File configFile = file(new File(‘src/config.xml’))

可以从Project的API发现file()方法能够接收任何形式的对象参数,它会将参数值转换为一个绝对文件对象,通常我们可以传一个String或File实例;如果传的路径是绝对路径,则会被直接构造为一个文件实例,否则会被构造为项目目录加上传递目录的文件对象;当然了,file()方法还能识别URL(譬如file:/some/path.xml等)。

文件集合:

文件集合其实是一组文件,Gradle使用FileCollection接口表示文件集合,Gradle API中许多类都实现了这个接口,譬如dependency configurations等。获取FileCollection实例的一种方法是Project.files(),我们可以传递任何数量的对象参数。如下:

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

总结

可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:

❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞

希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。

下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。

**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)

  • Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)

  • Flutter进阶学习全套手册

  • Flutter进阶学习全套视频

大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
减轻大家的负担。**
[外链图片转存中…(img-rFevSZtW-1712637411973)]
[外链图片转存中…(img-2w9Fo1Fm-1712637411974)]
[外链图片转存中…(img-g0GRRGzY-1712637411974)]
[外链图片转存中…(img-msMu4Ywn-1712637411974)]
[外链图片转存中…(img-uLmnZjOX-1712637411975)]
[外链图片转存中…(img-AX2oM8Cm-1712637411975)]
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
[外链图片转存中…(img-woZJ3C9Y-1712637411975)]

总结

可以看出,笔者的工作学习模式便是由以下 「六个要点」 组成:

❝ 多层次的工作/学习计划 + 番茄工作法 + 定额工作法 + 批处理 + 多任务并行 + 图层工作法❞

希望大家能将这些要点融入自己的工作学习当中,我相信一定会工作与学习地更富有成效。

下面是我学习用到的一些书籍学习导图,以及系统的学习资料。每一个知识点,都有对应的导图,学习的资料,视频,面试题目。

**如:我需要学习 **Flutter的知识。(大家可以参考我的学习方法)

  • Flutter 的思维导图(无论学习什么,有学习路线都会事半功倍)

[外链图片转存中…(img-dN4Md6R1-1712637411976)]

  • Flutter进阶学习全套手册

[外链图片转存中…(img-lINY4wzx-1712637411976)]

  • Flutter进阶学习全套视频

[外链图片转存中…(img-XrvSNdXW-1712637411976)]

大概就上面这几个步骤,这样学习不仅高效,而且能系统的学习新的知识。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-6pxerUyE-1712637411977)]

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值