Gradle自定義插件
在Gradle中創(chuàng)建自定義插件,Gradle提供了三種方式:
- 在build.gradle腳本中直接使用
- 在buildSrc中使用
- 在獨(dú)立Module中使用
開發(fā)Gradle插件可以在IDEA中進(jìn)行開發(fā),也可以在Android Studio中進(jìn)行開發(fā),它們唯一的不同,就是IDEA提供了Gradle開發(fā)的插件,比較方便創(chuàng)建文件和目錄,而Android Studio中,開發(fā)者需要手動(dòng)創(chuàng)建(但實(shí)際上,這些目錄并不多,也不復(fù)雜,完全可以手動(dòng)創(chuàng)建)。
在項(xiàng)目中使用
在Android Studio中創(chuàng)建一個(gè)標(biāo)準(zhǔn)的Android項(xiàng)目,整個(gè)目錄結(jié)構(gòu)如下所示:
├── app
│ ├── build.gradle
│ ├── libs
│ └── src
│ ├── androidTest
│ │ └── java
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── res
│ └── test
├── build.gradle
├── buildSrc
│ ├── build.gradle ---1
│ └── src
│ └── main
│ ├── groovy ---2
│ └── resources ---3
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
其中,除了buildSrc目錄以外,都是標(biāo)準(zhǔn)的Android目錄,而buildSrc就是Gradle提供的在項(xiàng)目中配置自定義插件的默認(rèn)目錄,開發(fā)Gradle要?jiǎng)?chuàng)建的目錄,也就是RootProject/src/main/groovy和RootProject/src/main/resources兩個(gè)目錄。
在配置完成后,如果配置正確,對(duì)應(yīng)的文件夾將被IDE所識(shí)別,成為對(duì)應(yīng)類別的文件夾。
創(chuàng)建buildSrc/build.gradle---1
首先,先來配置buildSrc目錄下的build.gradle文件,這個(gè)配置比較固定,腳本如下所示:
apply plugin: 'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
}
創(chuàng)建Groovy腳本---2
接下來,在groovy目錄下,創(chuàng)建一個(gè)Groovy類(與Java類似,可以帶包名,但Groovy類以.grovvy結(jié)尾),如圖所示:

在腳本中通過實(shí)現(xiàn)gradle的Plugin接口,實(shí)現(xiàn)apply方法即可,腳本如下所示:
package com.xys
import org.gradle.api.Plugin
import org.gradle.api.Project
public class MainPluginForBuildSrc implements Plugin<Project> {
@Override
void apply(Project project) {
project.task('testPlugin') << {
println "Hello gradle plugin in src"
}
}
}
在如上所示的腳本的apply方法中,筆者簡(jiǎn)單的實(shí)現(xiàn)了一個(gè)task,命名為testPlugin,執(zhí)行該Task,會(huì)輸出一行日志。
創(chuàng)建Groovy腳本的Extension
所謂Groovy腳本的Extension,實(shí)際上就是類似于Gradle的配置信息,在主項(xiàng)目使用自定義的Gradle插件時(shí),可以在主項(xiàng)目的build.gradle腳本中通過Extension來傳遞一些配置、參數(shù)。
創(chuàng)建一個(gè)Extension,只需要?jiǎng)?chuàng)建一個(gè)Groovy類即可,如圖所示:

如上所示,筆者命名了一個(gè)叫MyExtension的groovy類,其腳本如下所示:
package com.xys;
class MyExtension {
String message
}
MyExtension代碼非常簡(jiǎn)單,就是定義了要配置的參數(shù)變量,后面筆者將具體演示如何使用。
在Groovy腳本中使用Extension
在創(chuàng)建了Extension之后,需要修改下之前創(chuàng)建的Groovy類來加載Extension,修改后的腳本如下所示:
package com.xys
import org.gradle.api.Plugin
import org.gradle.api.Project
public class MainPluginForBuildSrc implements Plugin<Project> {
@Override
void apply(Project project) {
project.extensions.create('pluginsrc', MyExtension)
project.task('testPlugin') << {
println project.pluginsrc.message
}
}
}
通過project.extensions.create方法,來將一個(gè)Extension配置給Gradle即可。
創(chuàng)建resources---3
resources目錄是標(biāo)識(shí)整個(gè)插件的目錄,其目錄下的結(jié)構(gòu)如下所示:
└── resources
└── META-INF
└── gradle-plugins
該目錄結(jié)構(gòu)與buildSrc一樣,是Gradle插件的默認(rèn)目錄,不能有任何修改。創(chuàng)建好這些目錄后,在gradle-plugins目錄下創(chuàng)建——插件名.properties文件,如圖所示:

如上所示,這里筆者命名為pluginsrc.properties,在該文件中,代碼如下所示:
implementation-class=com.xys.MainPluginForBuildSrc
通過上面的代碼指定最開始創(chuàng)建的Groovy類即可。
在主項(xiàng)目中使用插件
在主項(xiàng)目的build.gradle文件中,通過apply指令來加載自定義的插件,腳本如下所示:
apply plugin: 'pluginsrc'
其中plugin的名字,就是前面創(chuàng)建pluginsrc.properties中的名字——pluginsrc,通過這種方式,就加載了自定義的插件。
配置Extension
在主項(xiàng)目的build.gradle文件中,通過如下所示的代碼來加載Extension:
pluginsrc{
message = 'hello gradle plugin'
}
同樣,領(lǐng)域名為插件名,配置的參數(shù)就是在Extension中定義的參數(shù)名。
配置完畢后,就可以在主項(xiàng)目中使用自定義的插件了,在終端執(zhí)行g(shù)radle testPlugin指令,結(jié)果如下所示:
:app:testPlugin
hello gradle plugin
在本地Repo中使用
在buildSrc中創(chuàng)建自定義Gradle插件只能在當(dāng)前項(xiàng)目中使用,因此,對(duì)于具有普遍性的插件來說,通常是建立一個(gè)獨(dú)立的Module來創(chuàng)建自定義Gradle插件。
創(chuàng)建Android Library Module
首先,在主項(xiàng)目的工程中,創(chuàng)建一個(gè)普通的Android Library Module,并刪除其默認(rèn)創(chuàng)建的目錄,修改為Gradle插件所需要的目錄,即在buildSrc目錄中的所有目錄,如圖所示:

如上圖所示,創(chuàng)建的文件與在buildSrc目錄中創(chuàng)建的文件都是一模一樣的,只是這里在一個(gè)自定義的Module中創(chuàng)建插件而不是在默認(rèn)的buildSrc目錄中創(chuàng)建。
部署到本地Repo
因?yàn)槭峭ㄟ^自定義Module來創(chuàng)建插件的,因此,不能讓Gradle來自動(dòng)完成插件的加載,需要手動(dòng)進(jìn)行部署,所以,需要在插件的build.gradle腳本中增加Maven的配置,腳本如下所示:
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
group='com.xys.plugin'
version='2.0.0'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
相比buildSrc中的build.gradle腳本,這里增加了Maven的支持和uploadArchives這樣一個(gè)Task,這個(gè)Task的作用就是將該Module部署到本地的repo目錄下。在終端中執(zhí)行g(shù)radle uploadArchives指令,將插件部署到repo目錄下,如圖所示:

當(dāng)插件部署到本地后,就可以在主項(xiàng)目中引用插件了。
當(dāng)插件正式發(fā)布后,可以把插件像其它module一樣發(fā)布到中央庫,這樣就可以像使用中央庫的庫項(xiàng)目一樣來使用插件了。
引用插件
在buildSrc中,系統(tǒng)自動(dòng)幫開發(fā)者自定義的插件提供了引用支持,但自定義Module的插件中,開發(fā)者就需要自己來添加自定義插件的引用支持。在主項(xiàng)目的build.gradle文件中,添加如下所示的腳本:
apply plugin: 'com.xys.plugin'
buildscript {
repositories {
maven {
url uri('../repo')
}
}
dependencies {
classpath 'com.xys.plugin:plugin:2.0.0'
}
}
其中,classpath指定的路徑,就是類似compile引用的方式,即——插件名:group:version
配置完畢后,就可以在主項(xiàng)目中使用自定義的插件了,在終端執(zhí)行g(shù)radle testPlugin指令,結(jié)果如下所示:
:app:testPlugin
Hello gradle plugin
如果不使用本地Maven Repo來部署,也可以拿到生成的插件jar文件,復(fù)制到libs目錄下,通過如下所示的代碼來引用:
classpath fileTree(dir: 'libs', include: '\*.jar') // 使用jar
參考:https://docs.gradle.org/current/userguide/custom_plugins.html