Gradle之自定義插件的三種形式(六)

自定義Gradle插件主要有三種形式蜒车,分別是build.gradle中編寫续室、buildSrc工程項(xiàng)目中編寫勃刨、獨(dú)立項(xiàng)目或獨(dú)立module中編寫波材。

1. 在build.gradle中編寫自定義插件

對(duì)象插件是實(shí)現(xiàn)了org.gradle.api.plugins接口的插件,這個(gè)接口中只定義個(gè)一個(gè)簡(jiǎn)單的apply方法身隐,想要實(shí)現(xiàn)自定義插件就需要去實(shí)現(xiàn)org.gradle.api.plugins接口廷区。
Groovy、Java贾铝、Kotlin都可以作為實(shí)現(xiàn)插件的語(yǔ)言隙轻,在本文的示例中,使用Groovy作為實(shí)現(xiàn)語(yǔ)言垢揩。
在實(shí)際工作中我們很少會(huì)在build.gradle中編寫自定義插件玖绿,這里是為了帶大家寫個(gè)最簡(jiǎn)單的例子,可以最快最直接的了解什么是自定義插件叁巨。

1.1 這里使用AS來(lái)編輯斑匪,新建一個(gè)項(xiàng)目,在module中的build.gradle中鍵入以下內(nèi)容:
// Apply the plugin
apply plugin: GreetingPlugin

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('GreetingPluginTask') {
            doLast {
                println '自定義插件'
            }
        }
    }
}

在build.gradle中自定義了一個(gè)插件GreetingPlugin锋勺,在apply方法中創(chuàng)建一個(gè)名稱為GreetingPluginTask的任務(wù)蚀瘸。在AS的Terminal中輸入gradlew.bat GreetingPluginTask來(lái)執(zhí)行GreetingPluginTask任務(wù)。

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradle>gradle  GreetingPluginTask

> Task :app:GreetingPluginTask 
自定義插件


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

1.2 自定義插件擴(kuò)展

再舉一個(gè)簡(jiǎn)單的插件拓展例子庶橱,通過(guò)插件拓展來(lái)配置GreetingPluginTask的輸出字符串贮勃,如下所示。
build.gradle

apply plugin: GreetingPlugin
greeting.message="自定義插件拓展"http://2
class GreetingPluginPluginExtension{
    String message="from GreetingPlugin"
}
class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        def extension=project.extensions.create("greeting",GreetingPluginPluginExtension)//1
        project.task('GreetingPluginTask') {
            doLast {
                println extension.message
            }
        }
    }
}

GreetingPluginPluginExtension類中定義了message變量苏章,GreetingPluginPluginExtension是一個(gè)Groovy Bean(類似于JavaBean)寂嘉。注釋1處用于添加拓展插件GreetingPluginPluginExtension到插件列表中,名稱為greeting。注釋2處設(shè)置GreetingPluginPluginExtension的message值垫释。
Terminal中輸入gradlew.bat GreetingPluginTask來(lái)執(zhí)行GreetingPluginTask任務(wù)丝格。

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradle>gradle GreetingPluginTask

> Task :app:GreetingPluginTask 
自定義插件拓展


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

2. buildSrc工程項(xiàng)目

除了在build.gradle中編寫的自定義插件,還可以將插件的源代碼放在rootProjectDir/buildSrc/src/main/groovy目錄中棵譬,Gradle會(huì)自動(dòng)識(shí)別來(lái)完成編譯和測(cè)試显蝌。Android Studio會(huì)找rootPrjectDir/buildSrc/src/main/groovy目錄下的代碼。

坑:當(dāng)新建libraray module并命名為buildSrc后會(huì)提示Plugin with id'com.android.library' not found.

這是因?yàn)閎uildSrc是Android的保留名稱订咸,只能作為plugin插件使用曼尊,我們修改buildSrc的build.gradle文件后就不報(bào)錯(cuò)了。

具體流程如下:

2.1. 首先創(chuàng)建一個(gè)名為buildSrc的module脏嚷,注意骆撇,名稱必須為buildSrc
image
2.2. 然后將其它不需要的文件刪除,新建需要的文件夾和文件父叙,最后的目錄結(jié)構(gòu)如下圖所示:
image
2.3. 新建對(duì)應(yīng)的文件和文件夾之后神郊,工程開(kāi)始會(huì)不認(rèn)這個(gè)buildSrc,我們修改build.gradle:
apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

點(diǎn)擊Sync Now趾唱,完了之后發(fā)現(xiàn)groovy文件夾變藍(lán)色了

2.4. 在對(duì)應(yīng)的包下面新建YolynPlugin.groovy涌乳,輸入以下內(nèi)容
import org.gradle.api.Plugin
import org.gradle.api.Project

class YolynPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('yolynplugin') {
            doLast {
                println("this is YolynPlugin")
            }
        }
        println("welcome to YolynPlugin")
    }
}
2.5. 再在com.yolyn.plugin.properties文件中添加以下內(nèi)容(注意這里properties的名稱就是我們之后要引用這個(gè)插件時(shí)apply plugin:''引號(hào)填入的內(nèi)容)
implementation-class=YolynPlugin

這里的YolynPlugin就是我們創(chuàng)建的YolynPlugin.groovy文件,一定要對(duì)應(yīng)上甜癞,否則會(huì)報(bào)找不到的錯(cuò)誤夕晓。

2.6. 在app的gradle中去引用這個(gè)插件
apply plugin:  'com.yolyn.plugin'

com.yolyn.plugin是我們之前創(chuàng)建的properties的名稱

重新build一下

2.7. 在terminal中可以鍵入命令
gradle yolynplugin   
或者gradlew yolynplugin  
或者gradlew.bat yolynplugin

輸出內(nèi)容:

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle yolynplugin

> Configure project :app 
welcome to YolynPlugin

> Task :app:yolynplugin 
this is YolynPlugin


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

疑問(wèn)1
這里有一個(gè)疑問(wèn),為什么先打印出welcome to YolynPlugin,是因?yàn)閐oLast嗎悠咱,怎么解釋蒸辆?
疑問(wèn)2
我們?cè)賱?chuàng)建一個(gè)插件叫OtherPlugin.groovy

 import org.gradle.api.Plugin
import org.gradle.api.Project

class OtherPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('otherplugin') {
            doLast {
                println("this is OtherPlugin")
            }
        }
        println("Welcome To OtherPlugin")
    }
}   

然后同樣地在gradle-plugins中創(chuàng)建properties,在app下面的build.gradle引用

在Terminal中輸入gradle otherplugin

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle otherplugin

> Configure project :app 
welcome to YolynPlugin
Welcome To OtherPlugin

> Task :app:otherplugin 
this is OtherPlugin


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

發(fā)現(xiàn)YolynPlugin中的apply方法也執(zhí)行了

疑問(wèn)3
我們把兩個(gè)Plugin中的doLast去掉
我們?cè)僭赥erminal中輸入gradle otherplugin

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle otherplugin

> Configure project :app 
this is YolynPlugin
welcome to YolynPlugin
this is OtherPlugin
Welcome To OtherPlugin


BUILD SUCCESSFUL in 6s

發(fā)現(xiàn)全部都打印出來(lái)了析既,這是為什么躬贡?

  1. 對(duì)于疑問(wèn)1:
    我們看一下官方對(duì)Projec的task方法的介紹
Creates a Task with the given name and adds it to this project. Calling this method is equivalent to calling task(java.util.Map, String) with an empty options map.

After the task is added to the project, it is made available as a property of the project, so that you can reference the task by name in your build file. See here for more details

If a task with the given name already exists in this project, an exception is thrown.

throws:
    InvalidUserDataException If a task with the given name already exists in this project.

Parameters:
    name - The name of the task to be created

Returns:
    The newly created task object

大致意思是會(huì)創(chuàng)建一個(gè)給定名字的task放到這個(gè)project里面,調(diào)用這個(gè)方法相當(dāng)于調(diào)用這個(gè)task

再看一下Task的doLast方法:

Adds the given closure to the end of this task's action list. The closure is passed this task as a parameter when executed.

這樣就能解釋了眼坏,確實(shí)是因?yàn)閐oLast將任務(wù)添加到project的tasks的list的最后了逗宜,所以才最后執(zhí)行。具體還可以查看官方文檔的Project空骚,文檔在gradle安裝目錄的docs里面可以找到。

==疑問(wèn)二和疑問(wèn)三是為什么擂仍?囤屹??求解==

日后繼續(xù)研究
再看第三種形式

3. 獨(dú)立項(xiàng)目或獨(dú)立Module

無(wú)論是在build.gradle中編寫自定義插件逢渔,還是buildSrc項(xiàng)目中編寫自定義插件肋坚,都只能在自己的項(xiàng)目中進(jìn)行使用。如果想要分享給其他人或者自己用,可以在一個(gè)獨(dú)立的項(xiàng)目中編寫插件智厌,這個(gè)項(xiàng)目會(huì)生成一個(gè)包含插件類的JAR文件诲泌,有了JAR文件就很容易進(jìn)行分享了。

3.1 創(chuàng)建一個(gè)名為YolynPlugin的module

跟上面創(chuàng)建buildSrc一樣铣鹏,將其它文件刪除敷扫,并創(chuàng)建相應(yīng)的文件和文件夾,最終目錄結(jié)構(gòu)如下:

image
3.2 修改build.gradle
apply plugin:'groovy'
apply plugin: 'maven'
dependencies {
    //gradle sdk
    compile gradleApi()
    //groovy sdk
    compile localGroovy()
}

Sync Now

3.3 在com.example.yolynplugin下創(chuàng)建ModuleYolynPlugin.groovy(為了和上面的YolynPlugin區(qū)分)
import org.gradle.api.Plugin
import org.gradle.api.Project

class ModuleYolynPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task("moduleyolynplugin") {
            println("this is module yolynplugin")
        }
    }
}
3.4 在gradle-plugins文件夾下面創(chuàng)建com.example.yolynplugin.properties
implementation-class=ModuleYolynPlugin
3.5 將代碼上傳到倉(cāng)庫(kù)或者本地诚卸,這里是放到本地

在這個(gè)module的build.gradle追加下面內(nèi)容

group='com.example.yolynplugin'
version='1.0.0'
//group和version在后面會(huì)用到
uploadArchives {
    repositories {
        mavenDeployer {
              //提交到遠(yuǎn)程服務(wù)器:
              // repository(url: "http://www.xxx.com/repos") {
              //    authentication(userName: "admin", password: "admin")
              // }
            repository(url:uri('../repo'))
        }
    }
}

上面各個(gè)參數(shù)的邏輯意義參考官方文檔:
https://docs.gradle.org/current/dsl/index.html
這里直接將插件上傳到了本項(xiàng)目的根目錄葵第,點(diǎn)擊Build之后在Gradle窗口會(huì)看到uploadArchives

image

點(diǎn)擊uploadArchives會(huì)在本地生成插件相關(guān)的文件,比如我的目錄和文件如下圖所示

image

圖中的YolynPlugin-1.0.0.jar就是我們需要的插件jar包合溺。

3.6 去app下面的module中引用

在build.gradle中追加下面內(nèi)容

apply plugin: 'com.example.yolynplugin'//properties的名字
buildscript {
//repositories這個(gè)模塊的內(nèi)容告訴gradle去什么地址下載第三方的庫(kù)卒密。
    repositories{
        maven {
        url uri('../repo')
        }
    }
    dependencies{
                   //group:pluginName:version
        classpath 'com.example.yolynplugin:YolynPlugin:1.0.0'
    }
}

其中com.example.yolynplugin是group,YolynPlugin是自定義插件的名稱棠赛,1.0.0是版本號(hào)

也可以這么寫:

dependencies {
     classpath group: 'com.example.yolynplugin', name: 'YolynPlugin',
             version: '1.0.0'
 }

Sync Now

3.7 clean一下Project哮奇,然后make Project,在Terminal中輸入:gradle moduleyolynplugin
D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle moduleyolynplugin

> Configure project :app 
welcome to YolynPlugin
Welcome To OtherPlugin
this is module yolynplugin


BUILD SUCCESSFUL in 8s

三個(gè)插件都成功運(yùn)行

筆記來(lái)源于:
1.https://blog.csdn.net/huachao1001/article/details/51810328
2. http://liuwangshu.cn/application/gradle/6-custonplugin.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末睛约,一起剝皮案震驚了整個(gè)濱河市鼎俘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌痰腮,老刑警劉巖而芥,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異膀值,居然都是意外死亡棍丐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門沧踏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)歌逢,“玉大人,你說(shuō)我怎么就攤上這事翘狱∶匕福” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵潦匈,是天一觀的道長(zhǎng)阱高。 經(jīng)常有香客問(wèn)我,道長(zhǎng)茬缩,這世上最難降的妖魔是什么赤惊? 我笑而不...
    開(kāi)封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮凰锡,結(jié)果婚禮上未舟,老公的妹妹穿的比我還像新娘圈暗。我一直安慰自己,他們只是感情好裕膀,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布员串。 她就那樣靜靜地躺著,像睡著了一般昼扛。 火紅的嫁衣襯著肌膚如雪寸齐。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天野揪,我揣著相機(jī)與錄音访忿,去河邊找鬼。 笑死斯稳,一個(gè)胖子當(dāng)著我的面吹牛海铆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播挣惰,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼卧斟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了憎茂?” 一聲冷哼從身側(cè)響起珍语,我...
    開(kāi)封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竖幔,沒(méi)想到半個(gè)月后板乙,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡拳氢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年募逞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馋评。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡放接,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出留特,到底是詐尸還是另有隱情纠脾,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布蜕青,位于F島的核電站苟蹈,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏右核。R本人自食惡果不足惜汉操,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蒙兰。 院中可真熱鬧磷瘤,春花似錦、人聲如沸搜变。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)挠他。三九已至扳抽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間殖侵,已是汗流浹背贸呢。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拢军,地道東北人楞陷。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像茉唉,于是被迫代替她去往敵國(guó)和親固蛾。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359