Gradle Plugin入門(mén)使用

一、學(xué)習(xí)目標(biāo)

  • 1亥鸠、 了解 Gradle Plugin 的作用是什么妆够?
  • 2、 如何去定義一個(gè) Gradle Plugin负蚊?
  • 3神妹、 自定義插件擴(kuò)展Extension。

一家妆、Gradle Plugin 的作用是什么鸵荠?

  • 模塊化構(gòu)建腳本的功能
  • 公共的功能可以抽取出來(lái)成為插件,可以供多個(gè) build.gradle 使用伤极,增加復(fù)用性蛹找。

二、定義一個(gè) Gradle Plugin

2.1哨坪、插件的處理和應(yīng)用

為了將構(gòu)建腳本的邏輯封裝到插件中庸疾,Gradle 需要做以下兩件事:處理插件應(yīng)用插件到目標(biāo)中当编。

  • 處理插件

Gradle 會(huì)自動(dòng)找到插件所在的位置届慈,例如一個(gè) buildSrc 名字 module 就會(huì) Gradle 識(shí)別為插件工程。

  • 應(yīng)用插件

一旦插件被應(yīng)用到執(zhí)行的構(gòu)建腳本中,那么插件對(duì)應(yīng)的 apply(T target) 方法就會(huì)被調(diào)用金顿。

2.2臊泌、 Gradle Plugin 創(chuàng)建

將插件定義在 buildSrc 中,這里的 buildSrc 就是當(dāng)前工程下的一個(gè) module 揍拆,Gradle 規(guī)定當(dāng)一個(gè)module被命名為 buildSrc 時(shí)就會(huì)被當(dāng)成插件去處理渠概。

按照以下的步驟來(lái)創(chuàng)建一個(gè)簡(jiǎn)單的插件工程吧:

  • 1、在當(dāng)前工程下創(chuàng)建一個(gè) Java Library 的 module礁凡,起名字為 buildSrc

  • 2高氮、將 main/src/java 修改為 main/src/groovy


    項(xiàng)目結(jié)構(gòu)
  • 3、創(chuàng)建類(lèi)PluginTest實(shí)現(xiàn) Plugin 接口并覆寫(xiě) apply(T garget) 接口

Plugin<T> 是一個(gè)泛型接口顷牌,在定義插件是應(yīng)該將這個(gè)泛型填為 Project 即可剪芍。

class PluginTest implements Plugin<Project> {

    @Override
    void apply(Project project) {
        //定義一個(gè) Task 
        project.task("MyTask") {
            doLast {
                println "MyTask doLast invoke..."
            }
        }
    }
}
  • 4、在外部應(yīng)用這個(gè)插件
//在 app 下的 build.gradle 引用這個(gè)插件
apply plugin: PluginTest
  • 5窟蓝、驗(yàn)證效果

app module 引用了這個(gè) PluginTest 插件罪裹,因此 app 這個(gè) project 就有 MyTask 這個(gè)任務(wù)了,我們來(lái)執(zhí)行一下驗(yàn)證一下效果吧运挫。

./gradlew :app:MyTask      

好了状共,通過(guò)上面幾個(gè)步驟,就可以創(chuàng)建一個(gè)簡(jiǎn)單的 Gradle Plugin 工程了谁帕,但是回想一下峡继,我們新建一個(gè)工程之后,在 build.gradle 中匈挖,Gradle 會(huì)幫我們引用 Android 插件apply plugin: 'com.android.application'碾牌,它們引用方式就跟我們上面引用方式是不一樣哦。

那這種引用方式是怎么定義的呢儡循?

這里其實(shí)是給我們的 Plugin 起了個(gè)別名舶吗,然后在外部就是用這個(gè)別名來(lái)引用。接下來(lái)我們通過(guò)源碼來(lái)看看'com.android.application'`是怎么定義的择膝?

【舉例】Gradle Android Plugin 中定義了一個(gè)叫 AppPlugin 的插件誓琼,這個(gè)插件是 Gradle 插件對(duì) Android 的擴(kuò)展,內(nèi)部定義 Android 相關(guān)的一些東西肴捉,例如 我們所熟知 android{} 內(nèi)部的東西都是屬于 Gradle 插件對(duì) Android 的擴(kuò)展腹侣。詳細(xì)的內(nèi)容可以參考另一篇博客:從源碼角度分析 Gradle 插件對(duì) Android 的擴(kuò)展

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.plugin"
        minSdkVersion 15
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

        multiDexEnabled true
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

而這個(gè) AppPlugin 就是 build.gradle 引入 apply plugin: 'com.android.application',查看源碼齿穗,這個(gè)別名是定義在一個(gè)文件名上的傲隶,文件內(nèi)容對(duì)這個(gè) AppPlugin 的映射關(guān)系。

AppPlugin 別名

那么我們依樣畫(huà)葫蘆缤灵,我們也來(lái)定義一下我們插件的別名吧:

下面來(lái)看一下如何來(lái)聲明我們自己的 Plugin ID 的

  • 1伦籍、如下圖所示在 src/main/resources/META-INF.gradle-plugins文件夾下創(chuàng)建文件

因?yàn)椴寮?lèi)的包名為 com.example.buildsrc ,所以該文件明就是 包名.properties

buildSrc結(jié)構(gòu)
  • 2、文件內(nèi)容

文件內(nèi)容的 implementation-class 對(duì)應(yīng)的值為插件類(lèi)的全限名稱(chēng)腮出。

implementation-class=com.example.buildsrc.PluginTest
  • 3帖鸦、引用插件

在 app 下的 build.gradle 引用這個(gè)插件

apply plugin:'com.example.buildsrc'
  • 4、驗(yàn)證效果

app module 引用了這個(gè) PluginTest 插件胚嘲,因此 app 這個(gè) project 就有 MyTask 這個(gè)任務(wù)了作儿,我們來(lái)執(zhí)行一下驗(yàn)證一下效果吧。

./gradlew :app:MyTask      

好了馋劈,就這樣攻锰,我們也可以像引用 Android Gradle Plugin ID 一樣來(lái)引用我們自己的插件咯。

三妓雾、插件擴(kuò)展 Extension

什么是擴(kuò)展插件娶吞?

擴(kuò)展插件 Extension 就是用于 Plugin 與 Project 通訊用的。

【舉例】我們想在 build.gradle 中通過(guò)配置 Extension 相關(guān)的屬性 械姻,然后將 Extension 這個(gè)對(duì)象傳遞給我們自定義的 Plugin妒蛇。

下面我們還是基于 PluginTest 這個(gè)插件來(lái)定義一個(gè)簡(jiǎn)單的插件擴(kuò)展。

  • 1楷拳、定義 TestExtension 類(lèi)

我這里定義的是 Groovy Bean(跟 Java Bean 類(lèi)似)绣夺,內(nèi)部定義一個(gè) message 變量。

class TestExtension {
    String message;
}
  • 2欢揖、 將 TestExtension 添加到 project#extensions 集合中陶耍。
class TestPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {

        //TestExtension extension = project.getExtensions().create("testExt", TestExtension)
        //1.添加插件擴(kuò)展到project.extensions集合中
        project.extensions.add("testExt", TestExtension)
        project.task("TestTask") {
            doLast {
                //2.獲取外界配置的 TestExtension
                TestExtension extension = project.testExt
                //3.輸出插件擴(kuò)展屬性
                println ">>>>>>" + extension.message
            }
        }
    }
}
  • 3、 給插件擴(kuò)展屬性賦值

//build.gradle

//依賴(lài)我們定義的插件
apply plugin: 'com.example.plugin.extension'
testExt {
    //給插件擴(kuò)展的屬性賦值
    message  "helloworld"
}
  • 4她混、 測(cè)試驗(yàn)證
./gradlew :app:TestTask

> Task :app:TestTask 
當(dāng)前執(zhí)行的 Task TestTask
>>>>>>helloworld

插件擴(kuò)展在 Project 和 Plugin 之前傳遞數(shù)據(jù)如圖所示

插件擴(kuò)展

# 參考

記錄于 2019年2月23日

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末烈钞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子产上,更是在濱河造成了極大的恐慌棵磷,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晋涣,死亡現(xiàn)場(chǎng)離奇詭異仪媒,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)谢鹊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)算吩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人佃扼,你說(shuō)我怎么就攤上這事偎巢。” “怎么了兼耀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵压昼,是天一觀的道長(zhǎng)求冷。 經(jīng)常有香客問(wèn)我,道長(zhǎng)窍霞,這世上最難降的妖魔是什么匠题? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮但金,結(jié)果婚禮上韭山,老公的妹妹穿的比我還像新娘。我一直安慰自己冷溃,他們只是感情好钱磅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著似枕,像睡著了一般盖淡。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凿歼,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天禁舷,我揣著相機(jī)與錄音,去河邊找鬼毅往。 笑死牵咙,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的攀唯。 我是一名探鬼主播洁桌,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼侯嘀!你這毒婦竟也來(lái)了另凌?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤戒幔,失蹤者是張志新(化名)和其女友劉穎吠谢,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體诗茎,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡工坊,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了敢订。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片王污。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖楚午,靈堂內(nèi)的尸體忽然破棺而出昭齐,到底是詐尸還是另有隱情,我是刑警寧澤矾柜,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布阱驾,位于F島的核電站就谜,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏里覆。R本人自食惡果不足惜吁伺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望租谈。 院中可真熱鬧,春花似錦捆愁、人聲如沸割去。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)呻逆。三九已至,卻和暖如春菩帝,著一層夾襖步出監(jiān)牢的瞬間咖城,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工呼奢, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留宜雀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓握础,卻偏偏與公主長(zhǎng)得像辐董,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子禀综,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355