一個開源的項目自動化構建工具,創建在Apache Ant和Apache Maven概念的基礎上,並引入了基於Groovy的特定領域語言(DSL),而再也不使用XML形式管理構建腳本。同時,gradle仍是一個編程框架,可讓開發者使用編程的思想來實現應用構建。gradle的組成:android
生命週期 | 做用 |
---|---|
Initialzation初始化階段 | 解析整個工程中全部project(讀取setting.gradle文件),構建全部的project對應的Project對象 |
Configuration配置階段 | 解析全部的project對象中的task,構建好全部task的拓撲圖 |
Execution執行階段 | 執行具體的task及其依賴的task |
生命週期監聽:編程
// 配置階段開始前的監聽回調(即:在Initialzation與Configuration之間)
this.beforeEvaluate {}
// 配置階段完成後的監聽回調(即:在Configuration與Execution之間)
this.afterEvaluate {}
// gradle執行完畢後的回調監聽(即:在Execution以後)
this.gradle.buildFinished {}
// 與 this.beforeEvaluate {} 同樣
this.gradle.beforeProject {}
// 與 this.afterEvaluate {} 同樣
this.gradle.afterProject {}
複製代碼
在Idea中,一個項目就是Project,一個Project下能夠包含多個模塊(Module),一個Module下,又能夠有多個Module,其樹狀結構以下:api
雖然能夠在Module中繼續建立子Module,但通常狀況下,咱們不會這麼作,最多就兩層。bash
+Project
--+Module
----+Module
----+Module
--+Module
--+Module
複製代碼
而對於Gradle而言,Idea中的不管是Project仍是Module,都是project,故樹狀結構以下:閉包
每一個project下,都必定會有一個build.gradleapp
+project // rootProject
--+project // subProject
----+project
----+project
--+project
--+project
複製代碼
api | 做用 |
---|---|
getAllprojects() | 獲取工程中全部的project(包括根project與子project) |
getSubProjects() | 獲取當前project下,全部的子project(在不一樣的project下調用,結果會不同,可能返回null) |
getParent() | 獲取當前project的父project(若在rooProject的build.gradle調用,則返回null) |
getRootProject() | 獲取項目的根project(必定不會爲null) |
project(String path, Closure configureClosure) | 根據path找到project,經過閉包進行配置(閉包的參數是path對應的Project對象) |
allprojects(Closure configureClosure) | 配置當前project和其子project的全部project |
subprojects(Closure configureClosure) | 配置子project的全部project(不包含當前project) |
// rootProject build.gradle下配置:
// 一、Project project(String path, Closure configureClosure);
project('app') { Project project -> // 一個參數時,能夠省略不寫,這裏只是爲了明確參數的類型
apply plugin : 'com.android.application'
group 'com.lqr'
version '1.0.0-release'
dependencies {}
android {}
}
// 二、allprojects(Closure configureClosure)
allprojects {
group 'com.lqr'
version '1.0.0-release'
}
// 三、subprojects(Closure configureClosure)
subprojects { Project project ->
if(project.plugins.hasPlugin('com.android.library')){
apply from: '../publishToMaven.gradle'
}
}
複製代碼
父project中經過ext塊定義的屬性,子project能夠直接訪問使用框架
// rootProject : build.gradle
// 定義擴展屬性
ext {
compileSdkVersion = 25
libAndroidDesign = 'com.android.support:design:25.0.0'
}
// app : build.gradle
android {
compileSdkVersion = this.compileSdkVersion // 父project中的屬性,子project能夠直接訪問使用
...
}
dependencies {
compile this.libAndroidDesign // 也可使用:this.rootproject.libAndroidDesign
...
}
複製代碼
hasProperty('xxx'):判斷是否有在gradle.properties文件定義xxx屬性。 在gradle.properties中定義的屬性,能夠直接訪問,但獲得的類型爲Object,通常須要經過toXXX()方法轉型。maven
// gradle.properties
// 定義擴展屬性
isLoadTest=true
mCompileSdkVersion=25
// setting.gradle
// 判斷是否須要引入Test這個Module
if(hasProperty('isLoadTest') ? isLoadTest.toBoolean() : false) {
include ':Test'
}
// app : build.gradle
android {
compileSdkVersion = mCompileSdkVersion.toInteger()
...
}
複製代碼
api | 做用 |
---|---|
getRootDir() | 獲取rootProject目錄 |
getBuildDir() | 獲取當前project的build目錄(每一個project都有本身的build目錄) |
getProjectDir() | 獲取當前project目錄 |
File file(Object path) | 定位一個文件,相對於當前project開始查找 |
ConfigurableFileCollection files(Object... paths) | 定位多個文件,與file相似 |
copy(Closure closure) | 拷貝文件 |
fileTree(Object baseDir, Closure configureClosure) | 定位一個文件樹(目錄+文件),可對文件樹進行遍歷 |
// 打印common.gradle文件內容
println getContent('common.gradle')
def getContent(String path){
try{
def file = file(path)
return file.text
}catch(GradleException e){
println 'file not found..'
}
return null
}
// 拷貝文件、文件夾
copy {
from file('build/outputs/apk/')
into getRootProject().getBuildDir().path + '/apk/'
exclude {} // 排除文件
rename {} // 文件重命名
}
// 對文件樹進行遍歷並拷貝
fileTree('build/outputs/apk/') { FileTree fileTree ->
fileTree.visit { FileTreeElement element ->
println 'the file name is: '+element.file.name
copy {
from element.file
into getRootProject().getBuildDir().path + '/test/'
}
}
}
複製代碼
配置工程倉庫及gradle插件依賴ide
// rootProject : build.gradle
buildscript { ScriptHandler scriptHandler ->
// 配置工程倉庫地址
scriptHandler.repositories { RepositoryHandler repositoryHandler ->
repositoryHandler.jcenter()
repositoryHandler.mavenCentral()
repositoryHandler.mavenLocal()
repositoryHandler.ivy {}
repositoryHandler.maven { MavenArtifactRepository mavenArtifactRepository ->
mavenArtifactRepository.name 'personal'
mavenArtifactRepository.url 'http://localhost:8081/nexus/repositories/'
mavenArtifactRepository.credentials {
username = 'admin'
password = 'admin123'
}
}
}
// 配置工程的"插件"(編寫gradle腳本使用的第三方庫)依賴地址
scriptHandler.dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.tencent.tinker-patch-gradle-plugin:1.7.7'
}
}
// ============ 上述腳本簡化後 ============
buildscript {
// 配置工程倉庫地址
repositories {
jcenter()
mavenCentral()
mavenLocal()
ivy {}
maven {
name 'personal'
url 'http://localhost:8081/nexus/repositories/'
credentials {
username = 'admin'
password = 'admin123'
}
}
}
// 配置工程的"插件"(編寫gradle腳本使用的第三方庫)依賴地址
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.tencent.tinker-patch-gradle-plugin:1.7.7'
}
}
複製代碼
配置應用程序第三方庫依賴工具
compile: 編譯依賴包並將依賴包中的類打包進apk。 provided: 只提供編譯支持,但打包時依賴包中的類不會寫入apk。
// app : build.gradle
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar']) // 依賴文件樹
// compile file() // 依賴單個文件
// compile files() // 依賴多個文件
compile 'com.android.support:appcompat-v7:26.1.0' // 依賴倉庫中的第三方庫(即:遠程庫)
compile project('mySDK') { // 依賴工程下其餘Module(即:源碼庫工程)
exclude module: 'support-v4' // 排除依賴:排除指定module
exclude group: 'com.android.support' // 排除依賴:排除指定group下全部的module
transitive false // 禁止傳遞依賴,默認值爲false
}
// 棧內編譯
provided('com.tencent.tinker:tinker-android-anno:1.9.1')
}
複製代碼
provided的使用場景:
// copyApk任務:用於將app工程生成出來apk目錄及文件拷貝到本機下載目錄
task('copyApk') {
doLast {
// gradle的執行階段去執行
def sourcePath = this.buildDir.path + '/outputs/apk'
def destinationPath = '/Users/lqr/Downloads'
def command = "mv -f ${sourcePath} ${destinationPath}"
// exec塊代碼基本是固定的
exec {
try {
executable 'bash'
args '-c', command
println 'the command is executed success.'
}catch (GradleException e){
println 'the command is executed failed.'
}
}
}
}
複製代碼