http://www.zhihu.com/question/30432152
19 个回答
上面是维基上对Gradle的解释,相信一个没有接触过构建的人是不大能看明白的,当初我也是.下面是我对Gradle 通俗的理解:Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML。当前其支持的语言限于Java、Groovy和Scala,计划未来将支持更多的语言。
软件开发讲究代码复用,通过复用可以使工程更易维护,代码量更少..... 开发者可以通过继承,组合,函数模块等实现不同程度上的代码复用.但不知你有没有想过,软件开发也是一种工程作业,绝不仅仅是写代码,还涉及到工程的各种管理(依赖,打包,部署,发布,各种渠道的差异管理.....),你每天都在build,clean,签名,打包,发布,有没有想过这种过程,也可以像代码一样被描述出来, 也可以被复用.
举个例子
我是做Android开发的,你可知道国内有n个Android市场,n个手机品牌,n个手机尺寸......,一般公司都会针对不同的市场单独发包用来统计不同渠道的下载量等情况,可能需要针对不同(品牌,尺寸等各种硬件信息)的手机做一些特殊的处理,这个时候你可以针对不同的情况单独建一个工程,或者更好一点你可以通过一些变量来控制,像这样:
if(isMoto){do something}
else if(isHuawei){do something}
...
但这两种解决方法都有自己的缺点,特别是前一种有极大的代码重复.后一种稍微好一点,但这种方式的差异是运行时的,不是静态的,对于moto手机上的处理逻辑对华为手机来说一点作用也没有,但这一段针对moto手机的处理逻辑也被装到了华为手机上了,通过gradle的productFlavor与buildtype可以实现静态级的差异控制可以参考 如何通过Gradle实现一套代码开发不同特性的APK · ByGhui
说到前面的多渠道问题,不同的渠道一般会对应不同的渠道号,你当然可以通过修改一次打一个包这种纯手工的方式来生成你的多渠道包,但据听说国内某团购网站的Android App有100多个渠道.这里出现了什么?重复,反复的去打包而且这些包之前的差异很小(只是渠道号不同),和写代码一样我们应该复用,通过Gradle可以实现一个命令打出所有的渠道包,一个命令打出指定的渠道包.再复杂一点,你可能需要不同的渠道对应不同的签名文件,不同的icon,不同的服务器地址...这些都可以通过Gradle来方便的实现.
依赖管理:
做软件开发你可能需要依赖各种不同的jar,library.你当然可以通过将.jar/library工程下载到本地再copy到你的工程中,但不知你是否听说过国外有个叫 中央仓库的东西,在这个仓库里你可以找到所有你能想到以及你从来没听说过的jar,aar... The Central Repository Search Engine 这里可以找到所有你需要的依赖,而你需要的只是指定一个坐标,如下:
剩下的依赖的寻找,下载,添加到classpath等你都不需要去关心,通过这种方式来维护依赖的好处有以下几点:
- 依赖不会进入到你的版本控制仓库中(默认会缓存到~/.gradle/下)
- 方便卸载装载依赖(只是一条坐标依赖,不需要删除即可)
- 方便的版本管理,如上图中的2.3.3既是picasso的版本号,若改为+就表示从中央仓库中下载最新的版本
- 不同工程的相同依赖不会存在重复副本(只在~/.gradle下存在一份)
这方面我没怎么接触过,但据我所知通过一些插件,可以实现自动将你的输出(.jar,.apk,.war...)上传到指定仓库,自动部署...
罗哩罗嗦说了这么多,不知大家有没有理解
总结一下:
- Gradle是一种构建工具,它可以帮你管理项目中的差异,依赖,编译,打包,部署......,你可以定义满足自己需要的构建逻辑,写入到build.gradle中供日后复用.
- Gradle不是一种编程语言,它不能帮你实现软件中的任何实际功能
###
赞同过百,放出之前相关分享的幻灯片
###
截止到现在( 1432311622353)共收到342个赞同与感谢, 再次感谢大家的支持!如果你觉得我的分享对你有帮助, 请关注我! 以后我会分享更多更优质的内容给大家.
说好的幻灯片在这里
(是之前在letv时一次内部分享的幻灯片,内容有删减(涉及到公司具体项目的部分),此幻灯片参考了很多其它的资料,内部的链接很值得大家打开看看 )
Ant和Maven都是基于XML的构建工具,Gradle是用Groovy编写的构建工具,Groovy是JVM衍生的与JAVA语法高度兼容的动态强类型语言。
Gradle通过编写一个名为build.gradle的脚本文件对项目进行设置,再根据这个脚本对项目进行构建(复杂的项目也有其他文件)
Gradle 脚本本质上就是Groovy脚本,只不过高度利用了groovy的语法糖,例如省略方法参数括号和省略句尾分号等,让代码看起来像DSL。
所以几乎所有java和groovy支持的语法,它的脚本都支持。(使用JAVA和GROOVY的SDK应该也是没问题的)
Gradle支持基于惯例的构建,并有丰富的适合不同情景下的插件库,光有官方用户手册支持的就有20多种,方便构建。
Gradle里有两个基本概念:项目(projects)和任务(tasks)。项目由多个任务组成,一个项目可以理解为提供给不同设备的构建版本,如桌面版、网页版、安卓版、iOS版等等,也可以理解为一种行为,例如部署应用到生产环境。任务相当于Ant的target,可以理解成一个构建中原子性的工作,例如编译、打包、执行等。需要注意的是,Ant中他自己的命令例如javac、copy等也叫做task,但Ant的task远没有Gradle的task那么自由。
Gradle的构建分两个阶段,第一阶段是设置阶段(configuration phase),分析构建脚本,处理依赖关系和执行顺序等,脚本本身也需要依赖来完成自身的分析。第二阶段是执行阶段(execution phase),此阶段真正构建项目并执行项目下的各个任务。
Ant与Maven对于Gradle,前者编写容易,但功能有限,需要人工操作的过程也多;后者依托于庞大的依赖仓库,因此有着强大的外部依赖管理,但添加本地依赖并不方便,且项目不能灵活修改。而Gradle能很好地结合Ant与Maven各自的优点,可以随意的编写任务并组合成项目,直接利用Maven仓库,并且能很好的支持传递依赖和内部依赖。(本部分为个人主观意见,可能与大多数人的意见并不相同)(其实也都是别人的个人主观意见,来源于我当初搜索的Gradle相关文章内容)
通俗一点类比成吃饭的话,大致就是:Ant是自己买菜洗菜烧水做饭,Maven是去饭店点餐,Gradle是3D打印食物。
Android Studio系列教程四--Gradle基础
Android Studio系列教程五--Gradle命令详解与导入第三方包
Android Studio系列教程六--Gradle多渠道打包
通俗的说:gradle是打包用的。
你觉得解决你的问题了吗?如果没解决,那是你的问题提得不够好。比如我猜你应该提:为什么要打包发布,打包发布有几种常见方法,为什么这些常见方法中要选gradle,等等。
针对我猜的这些内容,通俗的讲是这样的:
以在eclipse里面写java程序为例
为什么需要打包:
最初写完了,直接右键run就可以了。但是程序写完了毕竟是要发布到服务器上或者给别人用的,你第一不可能让所有要运行的人都装个eclipse,第二不可能把源代码公布给所有人。所以你需要把你的代码发布成二进制形式,让其它环境方便运行,这就是打包。
为什么用ant
打包的时候要做很多事,比如说配置文件中的用户名和密码,你本地开发和程序实际运行时的内容肯定不一致,所以需要有两个文件,开发的时候用一个,实际运行的时候用一个。这样每次打包的时候都要重复的做这些事,ant可以让你用xml的形式把这些事情写成脚本,然后自动运行。
为什么用maven
你的项目要用很多jar包,比如你写日志要用个log4j吧,连数据库要用个connector吧。这年头写程序不用个spring都不好意思出门,下载下来的spring包打开一看,密密麻麻的好几十个jar,不知道用哪个不用哪个。而且,即便是你一狠心把这些jar包都放进来,很大可能性还是不能运行,因为还要依赖其它的jar包。哪天想升级个spring小版本,所有jar包都要重来一遍,你也不记得哪些是由于spring引进来的jar包了。
所以有了maven,你只要配置一下说我要用spring 3,所有jar包都给你下载好了,你直接运行就行了。赶明儿想升级版本,直接把3改成4,新的jar包也给你下载好了。
然后?
用了maven,jar包是方便了,但我打包的时候还是有好多事要做啊,然后你会发现maven实在是不知道怎么做这些事,于是开始怀念ant。
gradle就是又能干maven的活,又能干ant的活,用groove语言写脚本,表达能力还更强。
就这意思。
===
我也是这两天才看了两眼gradle,了解不深。简化版如下:
ant可以自动化打包逻辑。
maven也可以自动化打包,相比于ant,它多做的事是帮你下载jar包。
但是maven的打包逻辑太死板,定制起来太麻烦,不如ant好用。gradle就是又能自动下jar包,又能自己写脚本,并且脚本写起来还比ant好用的这么个东西。
像Ruby里面的bundler+rake,
像iOS中的cocoapods,
像node中的npm+grunt.
通俗的讲就是:你的项目需要哪些第三方库,它帮你把它们都下载下来,并且编译好放到指定的位置,你就直接可以import后用了。
它本身是基于Apache的ant和maven的,但都不是特别好用,要引入一个库,还得写好多行的XML,麻烦死了。而且他们在任务执行上都比较弱,所以gradle就逐渐发展壮大了并被Google所推崇了。
整个过程可以分成以下几个步骤:
- 编译源代码
- 运行单元测试和集成测试
- 执行静态代码分析、生成分析报告
- 创建发布版本
- 部署到目标环境
- 部署传递过程
- 执行冒烟测试和自动功能测试
defaultTasks 'taskB'
task taskA << {
println "i'm task A"
}
task taskB << {
println "i'm task B, and I depend on " + taskA.name
}
taskB.dependsOn taskA
运行命令$ gradle -q之后(参数q让Gradle不要打印错误之外的日志),就能看到如下的预期输出:
i'm task A
i'm task B, and I depend on taskA
执行完之后Gradle会生成相应的报告,如果没有问题就可以发布到生产环境中。
Gradle脚本是基于Groovy领域特定语言,也就是说构建文件也是代码,Maven引入的XML配置文件可读性和可扩展性比较差,Gradle可以让你像写代码一样写出容易维护、可复用、可读性好、易于理解的构建代码。
Gradle同样引入了依赖管理、仓库和标准项目布局,Gradle引入的领域特定语言使得添加和删除依赖非常方便,你只需要在dependency块里面添加一行代码,注明要在哪个配置部分引入依赖,以及要引入哪个依赖,比如:
dependencies {
compile('org.springframework:spring-core:2.5.6')//表示编译期依赖spring-core这个库
testCompile('junit:junit:4.7')//表示测试代码的时候依赖junit这个库
}
Gradle支持多项目构建,当你的项目变得越来越庞大的时候,维护起来会比较困难,Gradle多项目构建使得你可以根据代码的功能把项目分成几个子项目,比如web项目开发中把项目分成逻辑、视图和控制三个模块,每个模块可以有各自的配置和依赖,也可以定义通用的配置。
当你需要为不同的环境打生成不同的发布时,以往可能是为每一个目标环境新建一个过程,有了gradle你不需要重复的工作,你会很容易生成不同的版本,你可以指定多个版本共同的构建逻辑,也可以给他们单独指定一些脚本。
总而言之,Gradle并没有引入太新鲜的东西,它是一个结合Ant和Maven理念的优秀实现,最重要的就是引入了Groovy语言,使得构建代码更加容易维护、可读性强、易于扩展,给了你充分的自由去自定义你的项目。
依赖管理简单地说就是你只用写一行代码就可以自动帮你把jar/aar包下载下来并能被当前工程所使用。
自动化构建就是gradle可以通过一些命令去执行一些特有任务比如编译测试打包等等。
gradle相较ant,更加简单高效,并且能处理很多复杂的任务比如多渠道打包。
____________
本文
依赖:Android Studio, Gradle, 其中过程,
Android Studio使用Gradle来编译Android apk 本文大致讲述其中过程
Gradle
依赖:Apache Ant ,Apache Maven ,项目自动化建构工具 ,Groovy, 特定领域语言(DSL),
Gradle =>一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言(DSL)
Apache Ant => 由Apache 提供的自动化软件构建工具 (可以理解为其负责软件的编译) 开始于2000年左右
Apache Maven => 是由Apache 提供的管理项目的构建 报告和文档的软件项目管理工具 (我将其理解为 通过pom.xml来描述软件依赖关系 并提供一个云端类库) 开始于2001年左右
项目自动化建构工具 => 抽象项目编译过程 提供一个容易使用的接口的工具
Groovy => 一门编程语言 基于JVM 的面对对象的动态脚本语言
特定领域语言=>为了解决某个特定领域的问题 而编写的语言 一般基于其他语言
Android Studio =>2013年谷歌推出的Android开发环境 使用Gradle 作为编译工具
其中过程
依赖:grdle基本知识,编译过程,
Android Studio 使用Gradle做为Android apk的编译工具 在android studio执行run 实际上底层调用的是gradle 命令 由gradle再去使用Android SDK中编译工具 这主要是因为直接使用sdk的编译工具太麻烦太痛苦 而gradle提供了一个很好的接口 让我们能通过命令行来编译android apk
grdle基本知识
gradle通过解析build.gradle这个文件来运行
build.gradle 主要由task和一些配置组成,task之间有相互依赖关系 通过这些依赖关系和配置就能编译项目
可以通过 apply plugin 来加入一些默认的task 例如
apply plugin: 'java'
这是java的插件 他加入了许多编译java的task 如果你的目录结构正确 那么通过gradle 运行 task 就能编译java项目
编译过程
这是一个最简单的显示 hellowrold的 apk的文件结构
一个android项目实际上在gradle 的编译体系中属于 multi project build 每个使用gradle编译的android项目都有一个app文件夹 android项目源码就在这个文件夹下
gradle文件中放的是
一个jar包 当你的电脑中没有安装gradle 就会通过他来下载gradle 从而继续编译
build.gradle中的是
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
他只是通过
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
}
来描述插件的位置
gradle.properties 中是配置信息 在这里设置jvm的heapsize 什么的
settings.gradle 之前说了每个用gradle 的android 项目是一个multi project build 那么就需要指明有哪些project 这里我们就只有默认的app
local.properties中配置的是sdk的位置
gradlew.bat 和gradlew 分别是在windows 和linux下的执行gradle 命令的程序 例如在windows下要编译apk 就 .\gradlew assemble
进入到app文件夹
libs文件夹下放项目要用的jar包
src下就是正常的android 项目的源码了
build.gradle中是
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.misakimei.project"
minSdkVersion 19
targetSdkVersion 23
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.4.0'
testCompile 'junit:junit:4.12'
}
apply plugin: 'com.android.application'
使用从之前设定的
dependencies {
classpath 'com.android.tools.build:gradle:2.1.3'
}
得到的plugin 这个plugin导入了许多编译android apk 要用的task
接着是两个配置项 android 和dependencies
android中配置的是源码的编译中的一些设置 sdkversion什么的 详细的在 这里
dependencies中配置的是这个项目中要用的类库
compile fileTree(dir: 'libs', include: ['*.jar'])
表示包括之前在libs文件夹下的所有jar包
compile 'com.android.support:appcompat-v7:23.4.0'
这种表示增加appcompat-v7:23.4.0的依赖 gradle会自动下载配置 什么的 (嘛 这就不用手动下jar包了)
例如如果要用guava 的话直接加一行compile group: 'com.google.guava', name: 'guava', version: '11.0.2' 就好
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "24.0.1"
defaultConfig {
applicationId "com.misakimei.project"
minSdkVersion 19
targetSdkVersion 23
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:23.4.0'
compile group: 'com.google.guava', name: 'guava', version: '11.0.2'
testCompile 'junit:junit:4.12'
}
dependencies 的详细配置在 这里
gradle +特定的插件 使得编译时只要在意配置 无须再手敲 aapt javac gcc 什么的
over
Gradle是一个自动化编译工具。自动化编译工具有很多,例如Maven,Ant,Ivy。他们各有各的特点,而Gradle则是综合了他们的优点而诞生的编译工具。
我不知道为什么Android放弃了自身的adt插件,进而选择gradle作为默认编译工具,但在这里,我简单说一下,我对 Gradle 的一些看法:
1.Gradle 使用 Groovy 作为自己的默认开发语言:
2.Gradle 支持 Maven 和 Ivy 的仓库
- Groovy是一种JVM动态语言,原生支持Java语法,这对于大部分Java开发人员来说是一个好消息,因为不需要太大的学习成本。
3.Gradle 的plugin 功能
- 如果没有三方代码仓库,那么我们在本地就会拥有一大堆的libs文件,同时还需要维护他们之间的引用关系,这只能用丧心病狂来形容
- 所以Gradle中内置的Maven,Ivy仓库支持能够帮助我们维护仓库引用关系,从此代码库就干净了
- plugin插件我认为是gradle所有功能中最好的,他就像应用中的增强包一样,帮你完善编译过程。
- 而且plugin插件也可以由自己进行开发定制,并发布到公开仓库供别人使用
- 同时拥有了plugin之后,你也可以自己完成自己的程序编译工具。
然后我们再看看引入Gradle打包之后,AndroidStudio多了哪些功能:
其实并不是说google不能在自身的databinding框架中使用这些,而是既然已经有了一个gradle能够帮助他实现这些功能,他为什么还要费力不讨好的去做。
- flavor 多渠道包编译
- databinding 数据绑定
- 编译task定义
- 通过dsl描述依赖和编译规则
如果工作是安卓app,那gradle连工作量的1%都不到。
一开始构建好。
引包拆包的时候,改几条代码,出问题查资料。
足够了。
你查查android工程师的能力要求,有熟悉gradle这一条的么?
欢迎加入Gradle中文用户组,群号码:109752483
- Customize, configure, and extend the build process.
- Create multiple APKs for your app with different features using the same project and modules.
- Reuse code and resources across source sets.