在语法上是基于Groovy语言的(Groovy 是一种基于JVM的敏捷开发语言,能够简单的理解为强类型语言java的弱类型版本),在项目管理上是基于Ant和Maven概念的项目自动化建构工具。html
Java基础,命令行使用基础
官方文档:https://docs.gradle.org/current/dsl/
** Gradle使用指南:** https://gradle.org/docs/current/userguide/userguide
Android插件文档:https://github.com/google/android-gradle...
AndroidGradle使用文档:http://tools.android.com/tech-docs/new-build-system/user-guide
Groovy基础: http://attis-wong-163-com.iteye.com/blog/1239819
Groovy闭包的Delegate机制:http://www.cnblogs.com/davenkin/p/gradle-learning-3.htmljava
MacOS 下配置。在~/.bash_profile
中添加以下代码linux
#gradle 注意gradle-2.14.1是本身解压的路径 export GRADLE_HOME=${HOME}/gradle-2.14.1 PATH=${PATH}:${GRADLE_HOME}/bin export PATH
保存后在终端输入source ~/.bash_profile
回车执行让刚刚的配置生效。而后命令行输入gradle -v
查看是否安装成功。android
$ gradle -v ------------------------------------------------------------ Gradle 2.14.1 ------------------------------------------------------------ Build time: 2016-07-18 06:38:37 UTC Revision: d9e2113d9fb05a5caabba61798bdb8dfdca83719 Groovy: 2.4.4 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 JVM: 1.8.0_111 (Oracle Corporation 25.111-b14) OS: Mac OS X 10.12.2 x86_64
建立一个test_gralde
文件夹。而后在文件夹里面建立一个build.gradle
文件。注意文件名不要乱起。在build.gradle
中添加以下代码:git
task helloworld{ doLast{ println'Hello World!' } } #后者等同于下面的代码, task helloworld2 <<{ println "Hello World!" }
而后来运行一下:程序员
liuqiangs-MacBook-Pro:test_gralde liuqiang$ gradle helloworld :helloworld Hello World! BUILD SUCCESSFUL Total time: 1.52 secs This build could be faster, please consider using the Gradle Daemon: https://docs.gradle.org/2.14.1/userguide/gradle_daemon.html
咱们分析一下执行步骤。build.gradle是Gradle默认的构建脚本文件,执行Gradle命令的时候,会默认加载当前目录下的build.gradle脚本文件,固然你也能够经过 -b 参数指定想要加载执行的文件。这只是个最简单的task例子,后面详细介绍task的常见定义。github
这个构建脚本定义一个任务(Task),任务名字叫helloworld,而且给任务helloworld添加了一个动做,官方名字是Action,阅读Gradle源代码你会处处见到它,其实他就是一段Groovy语言实现的闭包,doLast就意味着在Task执行完毕以后要回调doLast的这部分闭包的代码实现。第二个方法中的“<<”表示向helloworld中加入执行代码。至于语法部分,基本是Groovy语法(包括一些语法糖,也就是写简写方式,若是写个JavaScript或者Python会好理解一些,可是仍是建议去读一下groovy的基本语法),加上一些DSL(domain specific language)的约定。shell
和Maven同样,Gradle只是提供了构建项目的一个框架,真正起做用的是Plugin。Gradle在默认状况下为咱们提供了许多经常使用的Plugin,其中包括有构建Java项目的Plugin,还有Android等。与Maven不一样的是,Gradle不提供内建的项目生命周期管理,只是java Plugin向Project中添加了许多Task,这些Task依次执行,为咱们营造了一种如同Maven般项目构建周期。bash
Gradle是一种声明式的构建工具。在执行时,Gradle并不会一开始便顺序执行build.gradle文件中的内容,而是分为两个阶段,第一个阶段是配置阶段,而后才是实际的执行阶段。
配置阶段,Gradle将读取全部build.gradle文件的全部内容来配置Project和Task等,好比设置Project和Task的Property,处理Task之间的依赖关系等。闭包
看一个基本结构的Android多Moudule(也就是gradle中的多Project Multi-Projects Build)的基本项目结构。
├── app #Android App目录 │ ├── app.iml │ ├── build #构建输出目录 │ ├── build.gradle #构建脚本 │ ├── libs #so相关库 │ ├── proguard-rules.pro #proguard混淆配置 │ └── src #源代码,资源等 ├── module #Android 另一个module目录 │ ├── module.iml │ ├── build #构建输出目录 │ ├── build.gradle #构建脚本 │ ├── libs #so相关库 │ ├── proguard-rules.pro #proguard混淆配置 │ └── src #源代码,资源等 ├── build │ └── intermediates ├── build.gradle #工程构建文件 ├── gradle │ └── wrapper ├── gradle.properties #gradle的配置 ├── gradlew #gradle wrapper linux shell脚本 ├── gradlew.bat ├── LibSqlite.iml ├── local.properties #配置Androod SDK位置文件 └── settings.gradle #工程配置
上面的是完整的AndroidStudio中的项目结构,咱们抽象成Gradle多个Project的样子
├── app │ ├── build.gradle #构建脚本 ├── module │ ├── build.gradle #构建脚本 ├── build.gradle #工程构建文件 ├── gradle │ └── wrapper #先不去管它 ├── gradle.properties #gradle的配置 ├── gradlew #gradle wrapper linux shell脚本 ├── gradlew.bat └── settings.gradle #工程配置
Gradle向咱们提供了一整套DSL,因此在不少时候咱们写的代码彷佛已经脱离了groovy,可是在底层依然是执行的groovy因此不少语法仍是Groovy的语法规则。
看一个AndroidStudio中app下的build.gradle的配置
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.0" defaultConfig { applicationId "me.febsky.demo" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:25.1.0' }
apply plugin: 'com.android.application'
这句实际上是Groovy语法糖,像Ruby和Js都有这种语法糖,apply其实是个方法,补上括号后的脚本:apply (plugin: 'com.android.application')
,看起来仍是有点别扭是不?还有个语法糖,若是方法参数是个map类型,那么方括号能够省略,进一步还原apply([ plugin: 'com.android.application'])
,不理解的能够去看下Groovy的map的写法,和js同样。因此这行的意思是:apply实际上是个方法,接收一个Map类型的参数。
总结两点:1. 方法调用,圆括号能够省略 2. 若是方法参数是个Map,方括号能够省略。
看上面的dependencies
这实际上是个方法调用。调用了Project的dependencies方法。只不过参数是个闭包,闭包的用法在文章开始给出了连接。咱们对其进行还原一下:
#方法调用省略了()咱们加上 dependencies ({ compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:25.1.0' })
提示一点:若是闭包是方法的最后一个参数,那么闭包能够放在圆括号外面
#因此代码还能写成这样 dependencies (){ compile fileTree(dir: 'libs', include: ['*.jar']) compile 'com.android.support:appcompat-v7:25.1.0' }
Groovy语言中的两个概念,一个是Groovy中的Bean概念,一个是Groovy闭包的Delegate机制。
Java程序员对JavaBeans和Getter/Setter方法确定不陌生,被设计用来获取/设置类的属性。但在Groovy中就不用那些没用的方法了。即Groovy动态的为每个字段都会自动生成getter和setter,而且咱们能够经过像访问字段自己同样调用getter和setter。好比Gradle的Project对象有个version属性(Property)下面这两行代码执行结果是同样的:
println project.version // Groovy println(project.getVersion()) // Java
Gradle的Project之间的依赖关系是基于Task的,而不是整个Project的。
Project:是Gradle最重要的一个领域对象,咱们写的build.gradle脚本的所有做用,其实就是配置一个Project实例。在build.gradle脚本里,咱们能够隐式的操纵Project实例,好比,apply插件、声明依赖、定义Task等,如上面build.gradle
所示。apply、dependencies、task等其实是Project的方法,参数是一个代码块。若是须要,也能够显示的操纵Project实例,好比:project.ext.myProp = 'myValue'
Task:被组织成了一个有向无环图(DAG)。Gradle中的Task要么是由不一样的Plugin引入的,要么是咱们本身在build.gradle文件中直接建立的。Gradle保证Task按照依赖顺序执行,而且每一个Task最多只被执行一次。
Gradle在默认状况下为咱们提供了几个经常使用的Task,好比查看Project的Properties、显示当前Project中定义的全部Task等。能够经过一下命令行查看Project中全部的Task:$ gradle tasks
(具体log再也不贴出来)。能够看到,Gradle默认为咱们提供了dependencies、projects和properties
等Task。dependencies用于显示Project的依赖信息,projects用于显示全部Project,包括根Project和子Project,而properties则用于显示一个Project所包含的全部Property。
**Tips: **查看Project中全部的Task:
$ gradle tasks
查看Project中全部的properties:$ gradle properties
在上面的build.gradle
中加入以下代码:
task myTask { doFirst { println 'hello' } doLast { println 'world' } }
这段代码的含义:给Project添加一个名为“myTask”的任务
用一个闭包来配置这个任务,Task提供了doFirst和doLast方法来给本身添加Action。
其实build.gradle脚本的真正做用,就是配置一个Project实例。在执行build脚本以前,Gradle会为咱们准备好一个Project实例,执行完脚本以后,Gradle会按照DAG依次执行任务。
看下面代码文件路径~/Test/build.gradle
:
#1 task helloWorld << { println "Hello World" } #2 Test文件夹下建一个src目录,建一个dst目录,src目录下创建一个文件,命名为test.txt task copyFile(type: Copy){ from "src" into "dst" }
第一个这里的helloWorld是一个DefaultTask类型的对象,这也是定义一个Task时的默认类型,固然咱们也能够显式地声明Task的类型,甚至能够自定义一个Task类型。
第二个代码中(type:Copy)就是“显式地声明Task的类型”,执行gradle copyFile
test.txt也跑到dst中去了。
若是task声明在根Project的build.gradle中的allprojects()方法中,那么这个Task会应用于全部的Project。
Gradle不提供内建的项目生命周期管理,只是java Plugin向Project中添加了许多Task,这些Task依次执行,为咱们营造了一种如同Maven般项目构建周期。那么这些task是如何依次执行的这就用到声明的依赖关系taskA.dependsOn taskB
看下面代码:
task taskA << { println 'this is taskA from project 1' } task taskB << { println 'this is taskB from project 1' } taskA.dependsOn taskB
而后咱们在命令行运行:
$ gradle taskA
运行结果会先执行taskB的打印,而后执行taskA的打印
若是是Muliti-Project的模式,依赖关系要带着所属的Project,如
taskA.dependsOn ':other-project:taskC'
其中taskC位于和taskA不一样的Project中,相对于AndroidStudio来讲,就是位于不一样的Module下的build.gradle
中,而other-project为Module名字。
没有深刻研究,给出一个网上的例子:
apply plugin: DateAndTimePlugin dateAndTime { timeFormat = 'HH:mm:ss.SSS' dateFormat = 'MM/dd/yyyy' } class DateAndTimePlugin implements Plugin<Project> { //该接口定义了一个apply()方法,在该方法中,咱们能够操做Project, //好比向其中加入Task,定义额外的Property等。 void apply(Project project) { project.extensions.create("dateAndTime", DateAndTimePluginExtension) project.task('showTime') << { println "Current time is " + new Date().format(project.dateAndTime.timeFormat) } project.tasks.create('showDate') << { println "Current date is " + new Date().format(project.dateAndTime.dateFormat) } } } //每一个Gradle的Project都维护了一个ExtenionContainer, //咱们能够经过project.extentions进行访问 //好比读取额外的Property和定义额外的Property等。 //向Project中定义了一个名为dateAndTime的extension //并向其中加入了2个Property,分别为timeFormat和dateFormat class DateAndTimePluginExtension { String timeFormat = "MM/dd/yyyyHH:mm:ss.SSS" String dateFormat = "yyyy-MM-dd" }
每个自定义的Plugin都须要实现Plugin接口,除了给Project编写Plugin以外,咱们还能够为其余Gradle类编写Plugin。该接口定义了一个apply()方法,在该方法中,咱们能够操做Project,好比向其中加入Task,定义额外的Property等。
Wrapper,顾名思义,其实就是对Gradle的一层包装,便于在团队开发过程当中统一Gradle构建的版本,而后提交到git上,而后别人能够下载下来,这样你们均可以使用统一的Gradle版本进行构建,避免由于Gradle版本不统一带来的没必要要的问题。(因此要明白这个东西能够没有,有了只是为了统一管理,更加方便)
gradle 内置了生成wrapper的task,咱们能够命令行下执行:
$ gradle wrapper
生成后的目录结构以下(用过AndroidStudio的很熟悉了):
├── gradle │ └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew └── gradlew.bat
$ ./gradlew myTask
#Sat Jan 21 14:02:40 CST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-bin.zip
从上面内容和文件的名称均可以看出,这就是个java的配置文件,上面看到的是自动生成的,咱们也能够手动修改。而后看下各个字段的含义:
gradle wrapper –gradle-version 2.14
这样,这样就意味着咱们配置wrapper使用2.14版本的gradle,它会影响gradle-wrapper.properties中的distributionUrl的值,该值的规则是http://services.gradle.org/distributions/gradle-${gradleVersion}-bin.zip【参考文章】
http://www.infoq.com/cn/articles/android-in-depth-gradle/
http://blog.csdn.net/innost/article/details/48228651
做者:奋斗der小鸟 连接:https://www.jianshu.com/p/001abe1d8e95 來源:简书 简书著做权归做者全部,任何形式的转载都请联系做者得到受权并注明出处。