Gradle系列分2章
上篇Android Gradle Groovy自動化構建入門篇
下篇Android Gradle Groovy自動化構建進階篇html
上篇,咱們已經介紹了Gradle的基本語法,接下來讓咱們一塊兒學習下Gradle高級知識:構建腳本,自定義任務,構建生命週期,解決依賴衝突,多項目構建等高階技巧。java
- 在 project 根目錄新建****.gradle 文件;
- 經過
apply from
引入該配置文件,而後使用rootProject.ext
引入相關屬性.
//1.好比這裏新建文件爲config.gradle
ext {
versions = [
sdkMinVersion : 14,
sdkTargetVersion : 26,
...
]
depVersion = [
appCompatVersion : "26.+",
recyclerViewVersion : "26.0.0-alpha1"
]
deps = [
suport : [
appcompat : "com.android.support:appcompat-v7:${depVersion.appCompatVersion}",
recyclerview: "com.android.support:recyclerview-v7:${depVersion.recyclerViewVersion}"
]
]
}
// 2. 引入已聲明好的屬性
apply from: 'config/config.gradle'
android {
def versions = rootProject.ext.versions
compileSdkVersion versions.sdkCompileVersion
buildToolsVersion versions.toolsBuildVersion
...
}
dependencies {
def dependencies = rootProject.ext.deps
compile dependencies.suport.appcompat
}
複製代碼
Error:Execution failed for task ':test:processDebugManifest'.> Manifest merger failed with multiple errors, see logs
複製代碼
咱們通常的解決方案爲:命令行輸入gradlew processDebugManifest --stacktrace
.android
最後咱們在看個簡單的單機執行任務 git
因爲開發過程當中常常導入第三方jar包,一不當心就報jar包衝突這,這時咱們會執行 gradle app:dependencies
查看app重複依賴,而後在經過exclude剔除重複的jar。github
compile ('com.android.support:design:22.2.1')
{
exclude group: 'com.android.support'
}
複製代碼
其實當咱們點擊後Gradle會去尋找當前目錄下的 build.gradle 的文件,這個文件是 Gradle 的腳本文件,它裏面定義了工程和工程擁有的全部任務等信息。而後執行相關task。下面咱們一塊兒來一步步揭開它的神祕面紗吧。api
就像上面的截圖同樣,咱們知道,每個 Gradle 的項目都會包含一個或多個工程,每個工程又由一個或多個任務組成,一個任務表明了一個工做的最小單元,它能夠是一次類的編譯、打一個 JAR 包、生成一份 Javadoc 或者是向倉庫中提交一次版本發佈。bash
在任務中,我麼能夠利用
dependsOn
定義依賴關係,doFirst
、doLast
對現有任務加強。 咱們仍是使用 IDEA 開發工具打開以前的項目工程,把以前 build.gradle 文件中全部的內容所有刪除,編寫輸入以下代碼app
task hello {
doLast {
println 'Hello world!'
}
}
task release() {
doLast {
println "I'm release task"
}
}
// 添任務依賴關係
release.dependsOn hello
//對現有的任務加強
// 法方一,在doFirst動做中添加
hello.doFirst {
println 'Hello doFirst'
}
// 法方二 在doLast動做中添加
hello.doLast {
println 'Hello doLast'
}
複製代碼
打開命令行端終,執行命令:gradle -q release
,輸出結果以下:maven
task myTask {
ext.myProperty = "myValue"
}
task printTaskProperties {
doLast {
println myTask.myProperty
}
}
命令行執行 ➜ gradle -q printTaskProperties
myValue
複製代碼
固然咱們能夠對現有任務進行配置:禁用或者重寫。 首先咱們定義一個 myCopy 的任務,代碼以下:ide
task myCopy(type: Copy) {
from 'resources'
into 'target'
include('**/*.txt', '**/*.xml', '**/*.properties')
}
複製代碼
相似java有API文檔,Gradle也有相似文檔,Gradle 中不少其它經常使用的任務,小夥伴們能夠點擊查看, 若是咱們想重寫 copy任務可經過overwrite屬性爲 true 來現以下所示:
task copy(type: Copy)
task copy(overwrite: true) {
doLast {
println('overwrite the copy.')
}
}
命令行執行
> gradle -q copy
overwrite the copy.
複製代碼
最後咱們看下如何禁用某些任務。直接看代碼吧
copy.enabled = false
複製代碼
接下來咱們來自定義插件,有三種方式來編寫
在咱們構建項目的 build.gradle 腳本中直接編寫,這種方式的好處是插件會自動被編譯加載到咱們的 classpath 中,可是它有很明顯的侷限性,就是除了在包括它的腳本外別的地方沒法複用。
在咱們構建項目的rootProjectDir/buildSrc/src/main/groovy 目錄下編寫,Gradle 會自動編譯到當前項目的 classpath 中,該項目下全部編譯腳本均可以使用,可是除了當前項目以外的都沒法複用。
以單獨的工程方式編寫,這個工程最終編譯發佈爲一個 JAR 包,它能夠在多個項目或不一樣的團隊中共享使用。
接下來咱們一步步把按照第三種方式寫個Demo吧。
apply plugin: 'hello'
,裏面像這樣輸入插件的全路徑名字:implementation-class=org.gradle.HelloPlugin
- 繼承自DefaultTask的,使用TaskAction進行標註,這樣 Gradle 就會在任務執行的時候默認調用它
- 而後經過實現Plugin接口來實現自定義插件類,實現apply(Project project) 方法。
按照步驟,首先咱們新建MyTask.groovy文件,裏面僅僅是簡單聲明瞭一個成員變量,而後打印。
class MyTask extends DefaultTask {
String input = 'hello from MyTask'
@TaskAction
def greet() {
println input
}
}
複製代碼
而後咱們新建Hello.groovy文件.咱們向這個plugin添加了一個hello任務
,咱們知道gradle中能夠配置參數好比:defaultConfig {} ndk {}
等,其實gradle是使用 extension objects來現實給插件傳參,具體實現看下面代碼的註釋:
class Hello implements Plugin<Project> {
@Override
void apply(Project project) {
// 向extension container保存para參數,並應用給HelloPluginExtension
project.extensions.create("para", HelloPluginExtension)
// 向project對象添加hello任務
project.task('hello',type:MyTask) {
input = 'Hello Plugin input!'
doLast {
println "${project.para.first}${project.para.last}"
}
}
}
}
複製代碼
build.gradle
中輸入//使用 maven-publish 插件先發布到本地
apply plugin: 'maven-publish'
publishing{
publications {
mavenJava(MavenPublication) {
from components.java
groupId 'org.gradle'
artifactId 'customPlugin'
version '1.0-SNAPSHOT'
}
}
repositories{
maven {
// change to point to your repo, e.g. http://my.org/repo
url "../repo"
}
}
}
複製代碼
點擊publish任務,看到成功發佈工程到本地倉庫../repo中了。
Project.fileTree(java.util.Map)
建立,可使用過慮條件來包含或排除相關文件。// 指定目錄建立文件樹對象
FileTree tree = fileTree(dir: 'src/main')
// 給文件樹對象添加包含指定文件
tree.include '**/*.java'
//andoid中使用文件樹
implementation fileTree(include: ['*.jar'], dir: 'libs')
複製代碼
注意 settings.gradle
引入的module纔會參與編譯include ':app', ':plugin_common', ':plugin_gallery'
,能夠在跟guild.gradle
中統一設置公共行爲;好比下圖添加一個hello任務。
一個工程的路徑爲:以冒號(: 它表明了根工程)開始,再加上工程的名稱。例如「:common」。 一個任務的路徑爲:工程路徑加上任務名稱,例如「:common:hello」. 好比:僅僅執行 gradle :plugin_common:hello