Groovy語法
Groovy是運(yùn)行于JVM上的動(dòng)態(tài)語言(在運(yùn)行時(shí)不用指定變量類型,動(dòng)態(tài)改變數(shù)據(jù)類型 )
${}用于一般替代字串或者表達(dá)式
閉包
閉包是可以用作方法參數(shù)的代碼塊,象是方法指針,代碼在某處被定義然后在其后的調(diào)用處執(zhí)行。
定義閉包
{ [closureParameters -> ] statements }
調(diào)用
閉包對(duì)象.call(參數(shù))
閉包對(duì)象(參數(shù))
參數(shù)
{ int a, int b=2 -> a+b }
參數(shù)類型可選
參數(shù)可以設(shè)定默認(rèn)值
用逗號(hào)分隔
隱含參數(shù)
當(dāng)閉包沒有顯式定義參數(shù)列表時(shí),有一個(gè)隱式的it參數(shù)
閉包的簡寫
閉包作為閉包或方法的最后一個(gè)參數(shù),可以將閉包從參數(shù)圓括號(hào)中提取出來接在最后
如果閉包是唯一的一個(gè)參數(shù),則閉包或方法參數(shù)所在的圓括號(hào)也可以省略
對(duì)于有多個(gè)閉包參數(shù)的,只要是在參數(shù)聲明最后的,均可以按提取省略
Gradle文件操作
確定文件的位置
Project.file(java.lang.Object)方法
File configFile = file('src/config.xml')
文件集合
Project.files(java.lang.Object[])方法
可以把集合,迭代變量,map和數(shù)組傳遞給files()方法。它們會(huì)被展開,并且內(nèi)容會(huì)轉(zhuǎn)換為 File 實(shí)例
FileCollection collection = files('src/file1.txt',
new File('src/file2.txt'),
['src/file3.txt', 'src/file4.txt'],
Paths.get('src', 'file5.txt'))
文件樹
按照層次結(jié)構(gòu)劃分的文件集合
def myTree = fileTree(dir:'src', excludes:['**/ignore/**', '**/.data/**'])
task copy(type: Copy) {
from myTree
}
include 和 exclude 的含義:
org.gradle.api.tasks.util.PatternFilterable接口定義的方法
- '*' 匹配任意數(shù)量的字符
- '?' 匹配任意一個(gè)字符
- '**' 匹配任意數(shù)量的目錄或文件
task copyAllPdfReportsForArchiving(type: Copy) {
from "${buildDir}/reports"
include "**/*.pdf"
into "${buildDir}/toArchive"
}

Gradle 依賴管理
依賴管理包括兩部分,對(duì)獲取依賴的管理以及生成發(fā)布的管理
涉及內(nèi)容:管理依賴傳遞,解決版本沖突,使用
多數(shù)項(xiàng)目都不是完全獨(dú)立的,而是需要依賴其他的項(xiàng)目
Gradle從遠(yuǎn)程倉庫,本地目錄,或者多項(xiàng)目構(gòu)建中的另外一個(gè)項(xiàng)目獲取依賴
依賴類型
常見依賴類型
- 外部模塊依賴
- 項(xiàng)目依賴
- 文件依賴
- Client module dependency (外部模塊中的一種,修改部分?jǐn)?shù)據(jù))
外部依賴
外部依賴通過group,name,version三個(gè)屬性標(biāo)識(shí)
dependencies {
compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final'
}
快捷方式group:name:version
dependencies {
compile 'org.hibernate:hibernate-core:3.6.7.Final'
}
項(xiàng)目依賴
dependencies {
compile project(':shared')
}
文件依賴
dependencies {
runtime files('libs/a.jar', 'libs/b.jar')
runtime fileTree(dir: 'libs', include: '*.jar')
}
倉庫Repositories
外部依賴是通過倉庫來查找的
repositories {
mavenCentral()
jcenter()
maven {
url "http://repo.mycompany.com/maven2"
}
}
同時(shí)還可以利用Gradle把jar包上傳到遠(yuǎn)程倉庫(publication artifacts)
排除依賴傳遞
gradle dependencies 查看依賴
| | \--- com.android.support:recyclerview-v7:25.3.1 -> 25.4.0
| | +--- com.android.support:support-annotations:25.4.0
| | +--- com.android.support:support-compat:25.4.0
| | | \--- com.android.support:support-annotations:25.4.0
| | \--- com.android.support:support-core-ui:25.4.0
| | +--- com.android.support:support-annotations:25.4.0
| | \--- com.android.support:support-compat:25.4.0 (*)
25.3.1 -> 25.4.0是由于默認(rèn)會(huì)優(yōu)先版本高的依賴
(*)表示這個(gè)依賴被忽略了,這是因?yàn)橐呀?jīng)有其他依賴傳遞了這個(gè)依賴
compile ('com.android.support:appcompat-v7:22.1.1@aar') {
transitive = true//傳遞相關(guān)的依賴
}
排除模塊
dependencies {
compile('org.hibernate:hibernate:3.1') {
//排除某個(gè)傳遞的依賴
exclude module: 'cglib' /通過模塊名稱
exclude group: 'org.jmock' //通過組名
exclude group: 'org.unwanted', module: 'iAmBuggy' //通過組名和模塊名稱
}
}
Build生命周期
Gardle所有的構(gòu)建任務(wù),最終組成一個(gè)有向無循環(huán)圖
在任何任務(wù)執(zhí)行之前,都會(huì)先構(gòu)造出一個(gè)完整的依賴圖
構(gòu)建階段
一個(gè)Gradle構(gòu)建有三個(gè)明顯的階段
- 初始化階段(Initialization),通過
setting.gradle決定哪些project參加構(gòu)建,并創(chuàng)建相應(yīng)的Project實(shí)例 - 配置階段(Configuration),會(huì)去執(zhí)行所有工程的
build.gradle腳本 - 執(zhí)行階段(Execution),根據(jù)gradle命令傳遞過來的task名稱,執(zhí)行相應(yīng)的任務(wù)集合
示例
settings.gradle 文件
println 'initialization phase 1'
build.gradle 文件
println 'configuration phase 2'
task configured {
println 'configuration phase 3'
}
task test {
doLast {
println 'execution phase 5'
}
}
task testBoth {
doFirst {
println `execution phase 6'
}
doLast {
println 'execution phase 7'
}
println 'configuration phase 4'
}
執(zhí)行命令
gradle test testBoth
執(zhí)行的順序就是println字符串最后的數(shù)字
可以看到默認(rèn)的輸出是在配制階段執(zhí)行的,
對(duì)生命周期做出響應(yīng)
可以實(shí)現(xiàn)相應(yīng)的監(jiān)聽接口或者可以提供一個(gè)在收到通知時(shí)要執(zhí)行的閉包
例如 ProjectEvaluationListener 等接口
向具有某個(gè)屬性的項(xiàng)目添加任務(wù)
allprojects {
afterEvaluate { project ->
if (project.hasTests) {
println "Adding test task to $project"
project.task('test') {
doLast {
println "Running tests for $project"
}
}
}
}
}
Project.afterEvaluate()方法是在project評(píng)估(evaluated)后執(zhí)行的
插件plugin
Gradle的核心是一個(gè)框架,所有很有用的特性,例如編譯Java代碼的能力,都是通過plugin添加的
作用
- 提高復(fù)用,減少類似邏輯的配置過程
- 進(jìn)行更高層次的模塊化,加強(qiáng)可讀性和組織能力
- 封裝必要的邏輯
主要有兩類插件,一種是腳本(script),一種是二進(jìn)制(binary)插件
腳本插件添加進(jìn)入構(gòu)建腳本,用來更進(jìn)一步配置構(gòu)建,一般通過陳述的方式來控制構(gòu)建
二進(jìn)制腳本是實(shí)現(xiàn)Plugin接口的類,采用編程的方式來控制構(gòu)建
使用插件
- Resolve插件,查找到對(duì)應(yīng)版本的插件,添加到腳本的classpath中
- Apply插件,即執(zhí)行插件
Plugin.apply(T)
Script插件
apply from: 'other.gradle'
這一類的插件都是自行解析的,來自本地的文件系統(tǒng),或者遠(yuǎn)程
二進(jìn)制插件
通過提供 plugin id(一個(gè)全局唯一的標(biāo)識(shí)符)應(yīng)用插件
有核心插件(JavaPlugin) 和社區(qū)插件之分,核心插件可以使用簡稱(例如java)
通過 plugins DSL 使用插件
plugins {
id ?plugin id? version ?plugin version? [apply ?false?]
}
該模塊必須在構(gòu)建腳本的起始位置,除非是存在buildscript {}代碼塊,位于它的后
舊的使用插件的方式
apply plugin: 'java'
buildscript塊
當(dāng)構(gòu)建腳本需要使用外部庫時(shí),通過buildscript方法把已經(jīng)發(fā)布的二進(jìn)制插件的jar文件添加到腳本的classpath
總之,buildscript塊是用來配置Gradle自己需要的倉庫和依賴
buildscript {
repositories {
jcenter()
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:0.4.1"
}
}
apply plugin: "com.jfrog.bintray"
java插件
內(nèi)部包含的task:
-
compileJavatask that compiles all the Java source files under src/main/java -
compileTestJavatask for source files under src/test/java -
testtask that runs the tests from src/test/java -
jartask that packages the main compiled classes and resources from src/main/resources into a single JAR named<project>-<version>.jar -
javadoctask that generates Javadoc for the main classes
舉例:添加JNI編譯任務(wù),將so文件打包
String LibPath = "src/main/c++"
task buildJNILib(type: Exec){
workingDir "$LibPath"
commandLine "./buildJNI.sh"
}
clean {
delete fileTree("$LibPath") {include "**/*.so", "**/*.o"}
}
//add so file to the jar as a resource
processResources {
dependsOn buildJNILib
from ("$LibPath"){
include "*.so"
}
}