Android Gradle 自訂Task 詳解

來源:互聯網
上載者:User

標籤:str   組成   bmp   自訂   輸出   war   目標   gradle 環境   簡潔   

轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/76408024
本文出自【趙彥軍的部落格】

一:Gradle 是什麼
  • Gradle是一個基於Apache Ant和Apache Maven概念的項目自動化構建工具。
  • 它使用一種基於Groovy的特定領域語言(DSL)來聲明項目設定,拋棄了基於XML的各種繁瑣配置。面向Java應用為主。
  • 當前其支援的語言限於Java、Groovy、Kotlin和Scala,計劃未來將支援更多的語言。基於 groovy 指令碼構建,其 build 指令碼使用 groovy 語言編寫。

關於 gradle 相關運用,可以移步 :Android Gradle使用總結

二:groovy 是什麼

Groovy是一種動態語言,它和Java類似(算是Java的升級版,但是又具備指令碼語言的特點),都在Java虛擬機器中運行。當運行Groovy指令碼時它會先被編譯成Java類位元組碼,然後通過JVM虛擬機器執行這個Java位元組碼類。

關於 groovy 相關知識,移步到這裡:Groovy 使用完全解析

三:Gradle 的 Project 和 Tasks

每次構建(build)至少由一個project構成,一個project 由一到多個task構成。每個task代表了構建過程當中的一個原子性操作,比如編譯,打包,產生javadoc,發布等等這些操作。

gradle : 一個 project 包含多個 task,一個 task 包含多個 Action

project                   -- task1 (Action1、Action2...)                  -- task2 (Action1、Action2...)                  -- ... 
四:自訂 Task
  • 格式:
 task 任務的名字 {    //do some things }
  • 例子

build.gradle

//定義 task , 名字 hello task hello{    println "hello world"}//定義 task,名字 hello task(hello2){    println "hello world2"}//定義 task,名字 hello3 task (‘hello3‘){    println "hello world3"}
  • 在終端運行 gradle 命令
//執行 hello taskgradlew hello//執行 hello2 taskgradlew hello2//執行 hello3 taskgradlew hello3
五:建立Action

在上面的舉例中,是一個非正式的 task , 說非正式是因為建立的 task 裡面沒有 action 。task 本質上又是由一組被順序執行的 Action 對象構成,Action其實是一段代碼塊,類似於Java中的方法。

建立 Action 相關 API
 //在Action 隊列頭部添加Action Task doFirst(Action<? super Task> action); Task doFirst(Closure action); //在Action 隊列尾部添加Action Task doLast(Action<? super Task> action); Task doLast(Closure action);     //已經過時了,建議用 doLast 代替 Task leftShift(Closure action); //刪除所有的Action Task deleteAllActions();
小例子

build.gradle

//建立一個名字為hello的 task task hello {    //建立一個 Action , 添加到 Action 列表的頭部   doFirst(new Action<Task>() {       @Override       void execute(Task task) {           println "action1++++++++++"       }   })    //建立一個 Action , 添加到 Action 列表的頭部    doFirst {        println "action2++++++++++"    }}

在 Action 列表中添加了 兩個 Action , Action 列表如所示:

運行 hello task : gradle hello

運行結果:

action2++++++++++action1++++++++++
leftShift 說明

leftShift 的作用和 doLast 一樣,在action 列表尾部添加一個Action,只不過現在過時了,官方建議用 doLast 代替。下面舉個小例子:

build.gradle

task hello {    //在 Action 列表尾部添加一個 Action     leftShift {        println "+++++"    }}

leftShift 還有一種簡潔寫法,用 << 代替, 如下所示:

build.gradle

task hello <<{    //在 Action 列表尾部添加一個 Action     println "+++++"}

那麼問題來了,task 中的 Action 在什麼時候執行?

六:Gradle 生命週期1.初始化階段

會去讀取根工程中 setting.gradle 中的 include 資訊,決定有哪幾個工程加入構建,建立 project 執行個體,比如下面有三個工程: include ‘:app‘, ‘:lib1‘, ‘:lib2 。

2.設定階段

會去執行所有工程的 build.gradle 指令碼,配置 project對象,一個對象由多個工作群組成,
此階段也會去建立、配置task及相關資訊。

3.運行階段

根據gradle命令傳遞過來的task名稱,執行相關依賴任務。Task 的 Action 會在這個階段執行。

七:建立 Task 的另外一種方式

在上面講解了建立 task 的基本方式,其實 gradle api 給我們提供了其他的方式建立 task ,下面講解其他兩種方式。

  • tasks

build.gradle

//建立 hello2 tasktasks.create("hello2"){    doFirst {        println "hello2+++++"    }}
  • 自訂 DefaultTask 子類
class MyTask extends DefaultTask {        @TaskAction    void action(){        println "action1+++++"    }}//建立 hello3 tasktask hello3 (type: MyTask){    doLast{       println "action2+++++"    }}

運行 hello3 task: gradlew hello3

輸出

action1+++++
action2+++++

八: Task 依賴1、dependsOn

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}//task2 依賴 task1, 執行task2之前先執行task1task2.dependsOn task1

執行 task2

gradlew task2

執行效果

我是task1----
我是task2----

2、mustRunAfter兩個 task 依賴
task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}//task2 運行之前先運行task1task2.mustRunAfter task1
  • 執行 task1 : gradlew task1

    我是task1----

  • 執行 task2 : gradlew task2

    我是task2----

  • 同時執行 task1、task2 : gradlew task1 task2

    我是task1----
    我是task2----

三個 task 相互依賴

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}task task3 << {    println "我是task3----"}task2.mustRunAfter task1task3.mustRunAfter task1
  • 執行 gradlew task1 task2 task3

    我是task1----
    我是task2----
    我是task3----

  • 執行 gradlew task1 task3 task2

    我是task1----
    我是task3----
    我是task1----

在出現文法矛盾的情況下,依賴關係形成閉環,編譯器會報錯

task1.mustRunAfter task2task2.mustRunAfter task1

3、shouldRunAfter

形成依賴關係可有可無。

build.gradle

task task1 << {    println "我是task1----"}task task2 << {    println "我是task2----"}task1.shouldRunAfter task2

運行: gradlew task1 task2

我是task2----
我是task1----

在出現文法矛盾的情況下,依賴關係形成閉環,會自動打破閉環。不會報錯

九:系統預設 task

gradle 預設提供了很多 task 給我們使用,比如 copy、delete

1、copy

build.gradle

task 任務的名字 (type: Copy) {    //action }
  • Api 介紹
//資料來源目錄,多個目錄public AbstractCopyTask from(Object... sourcePaths)  //目標目錄,單一public AbstractCopyTask into(Object destDir) //過濾檔案 包含public AbstractCopyTask include(String... includes)//過濾檔案 排除public AbstractCopyTask exclude(String... excludes)//重新命名,老名字 新名字public AbstractCopyTask rename(String sourceRegEx, String replaceWith)//刪除檔案 Project 介面boolean delete(Object... paths);
小例子:
  • 複製圖片:單一資料來源
task copyImage(type: Copy) {    from ‘C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy‘    into ‘C:\\Users\\yiba_zyj\\Desktop‘}
  • 複製圖片:多個資料來源
task copyImage(type: Copy) {    from ‘C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy‘ ,          ‘C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy‘        into ‘C:\\Users\\yiba_zyj\\Desktop‘}
  • 複製圖片:過濾檔案

只會複製尾碼為 .jpg 的檔案

task copyImage(type: Copy) {    from ‘C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy‘    into ‘C:\\Users\\yiba_zyj\\Desktop‘    include "*.jpg" }
  • 複製檔案:過濾檔案,重新命名
task copyImage(type: Copy) {    from ‘C:\\Users\\yiba_zyj\\Desktop\\gradle\\copy‘    into ‘C:\\Users\\yiba_zyj\\Desktop‘    include "*.jpg"    exclude "image1.jpg"    rename("image2.jpg","123.jpg")}

檔案覆蓋規則

相同檔案覆蓋

Copy 類的繼承圖

Copy (類)   - AbstractCopyTask (抽象類別)  (from、 into、 include、rename)      -ConventionTask(抽象類別)       - DefaultTask (類)        - AbstractTask (抽象類別)           - TaskInternal (介面)            - Task(介面)                      -Comparable<Task>, ExtensionAware(介面)                -Project(介面)    (delete 方法)
2、Delete
  • 刪除 Android 更目錄的aaa 檔案

build.gradle

task deleteFile(type: Delete) {    //刪除Android 更目錄的aaa 檔案    delete ‘../aaa‘  }
  • 刪除案頭上的檔案

build.gradle

task deleteFile(type: Delete) {    //刪除系統案頭 delete     delete "C:\\Users\\yiba_zyj\\Desktop\\gradle\\delete"}
十:小技巧1、自訂 task 的名字用駝峰命名法

build.gradle

task deleteFile{    //do some things}

運行

gradlew dF 等價 gradlew deleteFile

打包時候運行 gradlew assembleRelease,可以簡寫成 gradlew aR

2、常見的 gradlew 命令

查看項目所有預設內建的 task,不包括自訂 task

gradlew tasks

查看所有 task (預設 task + 自訂task)

gradlew tasks --all

查看某個 task 的相關資訊,這些結果包含了任務的路徑、類型以及描述資訊等

gradlew help --task taskName

查看 gradle 版本

gradlew -version

3、給task 添加描述 description
task task1 << {    description = "這是一段描述資訊"    println "我是task1----"}
十一:Gradle 環境變數配置

在上面的介紹中,運行 task 的方式是用 gradlew , 那我們怎麼用 gradle 。如果在終端運行 gradle 就會提示 gradle 不是內部或外部命令,也不是可啟動並執行程式或批次檔。

‘gradle‘ 不是內部或外部命令,也不是可啟動並執行程式或批次檔。

官網下載:http://services.gradle.org/distributions/

下載完成後,我將壓縮包解壓放在 d 盤的 soft 目錄中。
環境變數

  • GRADLE_HOME

D:\soft\gradle-4.3-all

  • Path

    D:\soft\gradle-4.3-all\gradle-4.3\bin

參考資料

1、Android Gradle 必備實用技巧

2、Android Gradle使用總結

3、Groovy 使用完全解析

4、深入理解 Android Gradle 詳解

個人號:zhaoyanjun125 , 歡迎關注

Android Gradle 自訂Task 詳解

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.