美团面试java,Gradle脚本基础全攻略,android音频面试题

  • JDK版本必须是JDK6以上;

  • 因为Gradle自带Groovy库, 所以已安装的Groovy会被Gradle忽略;

具体Gradle环境配置好了以后如下图:

这里写图片描述

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

这里写图片描述

2 Gradle DSL基础

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

Gradle的实质是配置脚本,执行一种类型的配置脚本时就会创建一个关联的对象,譬如执行Build script脚本就会创建一个Project对象,这个对象其实就是Gradle的代理对象。下面给出来各种类型Gradle对应的对象类型:

| 脚本类型 | 关联对象类型 |

| — | — |

| Build script | Project |

| Init script | Gradle |

| Settings script | Settings |

Gradle的三种主要对象解释如下:

  • Project对象:每个build.gradle会转换成一个Project对象。

  • Gradle对象:构建初始化时创建,整个构建执行过程中只有这么一个对象,一般很少去修改这个默认配置脚本。

  • Settings对象:每个settings.gradle会转换成一个Settings对象。

可以看见,当我们编写指定类型Gradle脚本时我们可以直接使用关联对象的属性和方法;当然了,每个脚本也都实现了Script接口,也就是说我们也可以直接使用Script接口的属性与方法。

2-1 构建脚本Build script(Project)


在Gradle中每个待编译的工程都是一个Project(每个工程的build.gradle对应一个Project对象),每个Project在构建的时候都包含一系列Task,这些Task中很多又是Gradle的插件默认支持的。

PS:所谓的我们编写Gradle脚本,实质大多数时候都是在编写构建脚本Build script,所以说Project和Script对象的属性和方法等API非常重要。

每一个Project对象和build.gradle一一对应,一个项目在构建时都具备如下流程:

  1. 为当前项目创建一个Settings类型的实例。

  2. 如果当前项目存在settings.gradle文件,则通过该文件配置刚才创建的Settings实例。

  3. 通过Settings实例的配置创建项目层级结构的Project对象实例。

  4. 最后通过上面创建的项目层级结构Project对象实例去执行每个Project对应的build.gradle脚本。

2-2 初始化脚本Init script(Gradle)和设置脚本Settings script(Settings)


Gradle对象:

初始化脚本Init script(Gradle)类似于Gradle的其他类型脚本,这种脚本在构建开始之前运行,主要的用途是为接下来的Build script做一些准备工作。我们如果需要编写初始化脚本Init script,则可以把它按规则放置在USER_HOME/.gradle/相关目录下。譬如:

这里写图片描述

初始化脚本的Gradle对象代表了Gradle的调运,我们可以通过调用Project对象的getGradle()方法获得Gradle实例对象。

Settings对象:

在对工程进行配置(譬如多项目树构建)时Settings实例与settings.gradle文件一一对应,它用来进行一些项目设置的配置。这个文件一般放置在工程的根目录。譬如:

这里写图片描述

2-3 Build生命周期


Gradle的构建脚本生命周期具备三大步,如下:

这里写图片描述

可以看见,生命周期其实和上面构建脚本Build script的执行流程是可以关联上的。有了这个流程图我们接下里详细看下每个过程。

settings.gradle文件:

除了构建脚本文件,Gradle还定义了一个约定名称的设置文件(默认为settings.gradle)。该文件在初始化阶段被执行,对于多项目构建必须保证在根目录下有settings.gradle文件,对于单项目构建设置文件是可选的,不过建议还是写上。

如下是单项目构建的一个例子:

//settings.gradle

println ‘This is executed during the initialization phase.’

//build.gradle

println ‘This is executed during the configuration phase.’

task configured {

println ‘This is also executed during the configuration phase.’

}

task test << {

println ‘This is executed during the execution phase.’

}

task testBoth {

doFirst {

println ‘This is executed first during the execution phase.’

}

doLast {

println ‘This is executed last during the execution phase.’

}

println ‘This is executed during the configuration phase as well.’

}

运行构建结果:

gradle test testBoth

This is executed during the initialization phase.

This is executed during the configuration phase.

This is also executed during the configuration phase.

This is executed during the configuration phase as well.

:test

This is executed during the execution phase.

:testBoth

This is executed first during the execution phase.

This is executed last during the execution phase.

BUILD SUCCESSFUL

Total time: 1 secs

Gradle多项目构建:

多项目构建总是需要指定一个树根,树中的每一个节点代表一个项目,每一个Project对象都指定有一个表示在树中位置的路径;在设置文件中我们还可以使用一套方法来自定义构建项目树。

//分层布局的多项目构建settings.gradle文件

include ‘project1’, ‘project2:child’, ‘project3:child1’

上面例子中把project的路径作为了include方法的参数,譬如上面的’project3:child1’参数就指定了物理路径的project3/child1(project3/child1是相对于多项目根路径的相对路径),这也同时意味着会创建’project3’和’project3:child1’两个project。

//平面布局的多项目构建settings.gradle文件

includeFlat ‘project3’, ‘project4’

上面例子中includeFlat方法接受目录名作为参数,但是特别注意,这些项目目录必须是根目录的兄弟目录。

当然了,设置文件中创建的多项目树其实是由项目描述符来描述的,我们可以在设置文件中随时修改这些描述符。如下:

//settings.gradle

rootProject.name = ‘main’

project(‘:projectA’).projectDir = new File(settingsDir, ‘…/my-project-a’)

project(‘:projectA’).buildFileName = ‘projectA.gradle’

可以看见,如上例子通过描述符更改名称和项目目录,并且建立了一个项目的文件。

Gradle构建初始化Initialization:

在初始化阶段如果我们在根路径下直接指明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属性。上面的写法还有一种简写,如下规则:

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

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

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

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

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

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

总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

4981)]
img

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

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

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

总结:

各行各样都会淘汰一些能力差的,不仅仅是IT这个行业,所以,不要被程序猿是吃青春饭等等这类话题所吓倒,也不要觉得,找到一份工作,就享受安逸的生活,你在安逸的同时,别人正在奋力的向前跑,这样与别人的差距也就会越来越遥远,加油,希望,我们每一个人,成为更好的自己。

  • BAT大厂面试题、独家面试工具包,

  • 资料包括 数据结构、Kotlin、计算机网络、Framework源码、数据结构与算法、小程序、NDK、Flutter
    [外链图片转存中…(img-LXiGMbkH-1712533334982)]

本文已被CODING开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》收录

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

  • 14
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值