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 文件中全部的內容所有刪除,編寫輸入以下代碼markdown
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
,輸出結果以下:app
task myTask { ext.myProperty = "myValue" } task printTaskProperties { doLast { println myTask.myProperty } } 命令行執行 ➜ gradle -q printTaskProperties myValue 複製代碼
固然咱們能夠對現有任務進行配置:禁用或者重寫。 首先咱們定義一個 myCopy 的任務,代碼以下:maven
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中了。
最後用 IDEA 開發工具新建立一個 Gradle 工程來驗證咱們的插件。看到右側gradle任務中多了咱們添加的hello任務,點擊查當作功輸出了Hello world。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