Gradle DSL
在android{}塊中可以包含以下直接配置項(xiàng):
defaultConfig{} 默認(rèn)配置,是ProductFlavor類型。它共享給其他ProductFlavor使用
sourceSets{ } 源文件目錄設(shè)置,是AndroidSourceSet類型。
buildTypes{ } BuildType類型
signingConfigs{ } 簽名配置,SigningConfig類型
productFlavors{ } 產(chǎn)品風(fēng)格配置,ProductFlavor類型
testOptions{ } 測試配置,TestOptions類型
aaptOptions{ } aapt配置,AaptOptions類型
lintOptions{ } lint配置,LintOptions類型
dexOptions{ } dex配置,DexOptions類型
compileOptions{ } 編譯配置,CompileOptions類型
packagingOptions{ } PackagingOptions類型
jacoco{ } JacocoExtension類型。 用于設(shè)定 jacoco版本
splits{ } Splits類型。
在DSL文檔中,以上每個(gè)類型都有它的詳細(xì)配置選項(xiàng)
工程里有幾個(gè)gradle文件,一般為build.gradle。不要覺得他語法挺奇怪的,他不屬于標(biāo)記性語言(conf或者xml等),他是標(biāo)準(zhǔn)的groovy語言。他一轉(zhuǎn)換成標(biāo)準(zhǔn)java代碼。以下解釋經(jīng)過優(yōu)化,更便于理解!
有幾個(gè)概念要先理解一下:project,task,afterEvaluate周期,gradle的依賴(不是項(xiàng)目依賴,classpath環(huán)境),gradle插件簡介
project
介紹project之前先熟悉一下gradle風(fēng)格項(xiàng)目的目錄結(jié)構(gòu)。首先根目錄:
- app
- build.gradle
- gradlew
- gradlew.bat
- settings.gradle
- App下面就就是主工程。
- build.gradle是管理所有工程的的腳本,以及管理gradle編譯的依賴(classpath)。
- gradlew和gradlew.bat初始化環(huán)境變量,他就是項(xiàng)目構(gòu)建執(zhí)行的入口。
- setting.gradle用來注冊(cè)所有模塊。
以上目錄成為rootProject。在build.gradle里邊使用project使用,它代表rootProject。但是,如果在app下邊的build.gradle使用project的時(shí)候,就代表app工程。(以上project皆代表變量,這個(gè)變量擁有當(dāng)前模塊的一切信息,可以在build.gradle中任何地方使用它,只需要注意project指向問題)
afterEvaluate周期
afterEvaluate 這個(gè)回調(diào)需要了解一下,首先我們把gradle編譯項(xiàng)目分為兩步:構(gòu)建項(xiàng)目使用的gradle腳本和構(gòu)建項(xiàng)目。舉個(gè)例子:人吃飯需要飯,飯需要制作。那么做飯是第一步,吃飯時(shí)第二步。如果把做飯比作構(gòu)建gradle腳本,那么構(gòu)建項(xiàng)目就是吃飯。afterEvaluate這個(gè)回調(diào),就是吃飯的回調(diào)。告訴你飯熟了,接著該吃飯了。
在Gradle項(xiàng)目中,我們會(huì)注冊(cè)很多個(gè)ext參數(shù)或者android參數(shù),這些東西在飯熟之前是拿不到的。
task
項(xiàng)目構(gòu)建是一步一步完成的,比如有一個(gè)影響深遠(yuǎn)的哲學(xué)問題,把大象放進(jìn)冰箱分為幾步,先什么什么在什么什么。task就是這個(gè)步驟,android打包步驟這里不贅述,只需要明白它是由一個(gè)一個(gè)task串并聯(lián)起來的。
:app:preSitDebugBuild UP-TO-DATE
:app:compileSitDebugAidl UP-TO-DATE
:app:compileSitDebugRenderscript UP-TO-DATE
:courierMain:generateDebugRFile UP-TO-DATE
:app:checkSitDebugManifest
:courierMain:generateDebugSources UP-TO-DATE
:app:checkSitDebugManifest UP-TO-DATE
:app:generateSitDebugBuildConfig UP-TO-DATE
:app:rpGenerateSitDebugHostConfig
:app:generateSitDebugResources UP-TO-DATE
:app:mergeSitDebugResources UP-TO-DATE
:app:processSitDebugManifest UP-TO-DATE
:app:processSitDebugResources UP-TO-DATE
:app:generateSitDebugSources UP-TO-DATE
其中:app代表在app下,:理解為/就可以了,整句就是執(zhí)行根目錄下app下的什么什么task。UP-TO-DATE 使用緩存構(gòu)建,代表跳過。
在build.gradle中聲明一個(gè)task很容易。
task {
// code block1
doFirst {
// code block2
}
doLast {
// code block3
}
}
在飯熟之前,系統(tǒng)會(huì)自動(dòng)回調(diào)code block1和code block2的內(nèi)容。只有寫在doLast里邊的會(huì)在手動(dòng)出發(fā)之后執(zhí)行,這一點(diǎn)需要注意。
Task之間可以使用 dependOn進(jìn)行依賴,這樣就可以把一個(gè)一個(gè)task串聯(lián)起來,用來構(gòu)建項(xiàng)目。一個(gè)task同時(shí)對(duì)兩個(gè)task進(jìn)行依賴的時(shí)候,使用mustRunAfter進(jìn)行排序。task之間的依賴就不要搞得太復(fù)雜了。更多使用見官方文檔,這里只是了解。
classpath
Gradle構(gòu)建也需要有依賴,類似我們項(xiàng)目的dependencies。只不過它通常使用classpath聲明一個(gè)依賴。在rootProject的build.gradle中buildscript可以找到。
buildscript {
repositories {
flatDir name: 'localRepository', dir: "ma/repos"
maven {
url "http://nexus.sf-express.com/nexus/content/groups/public/"
}
}
configurations.all {
resolutionStrategy.cacheDynamicVersionsFor 0, 'seconds'
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}
dependencies {
//聲明依賴
classpath 'com.android.tools.build:gradle:3.1.3'
classpath 'com.sf.replugin:replugin-host-gradle:2.2.3.2462.311'
classpath 'com.jakewharton:butterknife-gradle-plugin:8.4.0'
classpath "io.lecon.moduleassistant:ma-lib:0.0.4.dev-SNAPSHOT"
}
}
這個(gè)gradle構(gòu)建工程使用了四個(gè)依賴,谷歌的android依賴,插件化的依賴,butterknife以及ma。他們都是為構(gòu)建gradle而服務(wù)的,原則上不涉及到我們要寫代碼的工程,只是更好的為我們寫代碼服務(wù)(做飯過程)。
所以你可以明白buildscript-> repositories-> maven和allprojects->repositories->maven雖然寫的一樣,但他們代表的意義確實(shí)不同的,一個(gè)服務(wù)于gradle構(gòu)建腳本(做飯),一個(gè)服務(wù)于所有子項(xiàng)目的依賴(吃飯)。
gradle插件
這個(gè)話題如果詳細(xì)說的話,需要很打的篇幅,這里只是簡單介紹一下。介紹一下能做到哪些東西。
Gradle的插件非常開放:
可以動(dòng)態(tài)增刪改查classpath,以及項(xiàng)目的dependencies,
動(dòng)態(tài)創(chuàng)建task,修改你build.gradle中的dsl。
以及實(shí)現(xiàn)動(dòng)態(tài)增加或者更改代碼(transform代碼掃描更改技術(shù)),butterknife中findviewbyid的生成和Replugin插件的生成(代碼生成技術(shù)和代碼插裝技術(shù))
獲取項(xiàng)目中的所有路徑,包括代碼(sourceSets),資源路徑,AndroidMainfest,以及Apk輸出路徑,甚至你可以干擾這些過程(task的doLast和dependOn)。
使用這個(gè),你甚至可以寫一個(gè)小型的Jvm程序,但別忘了,你要寫的代碼的是輔助項(xiàng)目開發(fā)。
在編寫代碼的時(shí)候,需要注意gradle的生命周期,明確他是在做飯還是吃飯時(shí)期,否則有些變量無法獲取。