Android Gradle 學習筆記(五):Gradle 任務 Task


在之前的學習中,我們了解到Gradle的構建工作都是由Task組合完成的。本節我們就來介紹一下 Task - 任務。

一、多種方式創建任務

在Gradle中,我們可以有很多種方式來創建任務。為什么有這么多種方式呢?這都依賴於Project提供的快捷方法以及TaskContainer提供的相關Create方法。所以我們閱讀一些Gradle腳本的時候,見到一些不熟悉的創建任務的方法也不要奇怪,一般分為以下幾種方式:

  • 第一種:直接以一個任務名字創建任務。
  • 第二種:以一個任務名字+一個對該任務配置的Map對象來創建任務。
  • 第三種:任務名字+閉包配置。
  • 第四種:任務名字+Map參數+閉包。
  • 第五種:使用TaskContainer創建任務,調研tasks.create方法創建任務。

二、多種方式訪問任務

其實我們在之前的學習的例子中,我們已經通過了一些方式訪問了任務。下面我們整理一下相關的方式:

  • 第一種:我們創建的任務都會作為項目(Project)的一個屬性,屬性名就是任務名,所以我們可以通過該任務名稱訪問和操作該任務。
  • 第二種:任務都是通過TaskContainer創建的,TaskContainer就是我們創建任務的集合,在Project中我們可以通過tasks屬性訪問TaskContainer,所以我們可以以訪問集合元素的方式訪問我們的任務。
  • 第三種:通過路徑訪問。方式有兩種:get & find,區別在於get的時候找不到就會拋出UnknownTaskException異常,而find在找不到任務的時候會返回null。
  • 第四種:通過名稱訪問。通過名字的訪問也有兩種:get & find,它們的區別和上面第三種介紹的一樣。

值得強調的是,通過路徑訪問的時候,參數可以是任務路徑也可以是任務的名字。但是通過名字訪問的時候,參數值只能是任務的名字,不能為路徑。

三、任務排序

其實並沒有真正的任務排序功能,這個排序不像我們想象的通過設置優先級或者Order順序實現,而是通過任務的shouldRunAfter和mustRunAfter這兩個方法,它們可以控制一個任務應該或者一定在某個任務之后執行。通過這種方式,你可以在某些情況下控制任務的執行順序,而不是通過強依賴的方式。

這個功能是非常有用的,比如我們設置的順序是,必須先執行單元測試,然后才能進行打包,這就保證了App的質量。類似的情況還有很多,比如必須要單元測試之后,才能進行集成測試,打包成功之后才能進行部署發布等。

舉例說明:

  • taskB.shouleRunAfter(taskA):表示taskB應該在taskA執行之后執行,這里的應該而不是必須。所以有可能任務順序並不會按預設的執行。
  • taskB.mustRunAfter(taskA):表示taskB必須在taskA執行之后執行,這個規則相對更加嚴格。

四、任務的onlyIf斷言

斷言就是一個條件表達式。Task有一個onlyIf方法,它接受一個閉包作為參數,如果該閉包返回true,則該任務執行,否則就跳過。這有很多用途,比如控制程序哪些情況下打什么包,什么時候進行單元測試,什么情況下執行單元測試的時候不執行網絡測試。

下面我們以一個打首發包的例子來說明:

final String BUILD_APPS_ALL="all";
final String BUILD_APPS_SHOUFA="shoufa";
final String BUILD_APPS_EXCLUDE_SHOUFA="exclude_shoufa";

task ex48QQRelease << {
    println "打應用寶的包"
}
task ex48BaiduRelease << {
    println "打百度的包"
}
task ex48HuaweiRelease << {
    println "打華為的包"
}

task ex48MiuiRelease << {
    println "打Miui的包"
}

task build {
    group BasePlugin.BUILD_GROUP
    description "打渠道包"
}

build.dependsOn ex48QQRelease,ex48BaiduRelease,ex48HuaweiRelease,ex48MiuiRelease

ex48QQRelease.onlyIf {
    def execute = false;
    if(project.hasProperty("build_apps")){
        Object buildApps = project.property("build_apps")
        if(BUILD_APPS_SHOUFA.equals(buildApps)
            || BUILD_APPS_ALL.equals(buildApps)){
            execute = true
        }else{
            execute = false
        }
    }else{
        execute = true
    }
    execute
}

ex48BaiduRelease.onlyIf {
    def execute = false;
    if(project.hasProperty("build_apps")){
        Object buildApps = project.property("build_apps")
        if(BUILD_APPS_SHOUFA.equals(buildApps)
                || BUILD_APPS_ALL.equals(buildApps)){
            execute = true
        }else{
            execute = false
        }
    }else{
        execute = true
    }
    execute
}

ex48HuaweiRelease.onlyIf {
    def execute = false;
    if(project.hasProperty("build_apps")){
        Object buildApps = project.property("build_apps")
        if(BUILD_APPS_EXCLUDE_SHOUFA.equals(buildApps)
                || BUILD_APPS_ALL.equals(buildApps)){
            execute = true
        }else{
            execute = false
        }
    }else{
        execute = true
    }
    execute
}

ex48MiuiRelease.onlyIf {
    def execute = false;
    if(project.hasProperty("build_apps")){
        Object buildApps = project.property("build_apps")
        if(BUILD_APPS_EXCLUDE_SHOUFA.equals(buildApps)
                || BUILD_APPS_ALL.equals(buildApps)){
            execute = true
        }else{
            execute = false
        }
    }else{
        execute = true
    }
    execute
}

在例子中,我們定義了4個渠道,其中百度和應用寶是首發包,另外兩個華為和MiUi不是首發包,通過build_apps屬性來控制我們要打哪些渠道包。

通過這種方式,我們在進行一些相關流程控制上會更加靈活。這在我們使用JenKins等CI工具進行自動化打包和部署的時候就能很好的體現出來。

五、多渠道打包(補充資料)

1.Gradle多渠道打包(動態設定App名稱,應用圖標,替換常量,更改包名,變更渠道):https://www.jianshu.com/p/533240d222d3

2.Android Gradle 多版本多APK打包,修改生成APK名稱:https://blog.csdn.net/aiynmimi/article/details/68944830

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM