自定義Gradle插件主要有三種形式,分別是build.gradle中編寫、buildSrc工程項目中編寫、獨立項目或獨立module中編寫。
1. 在build.gradle中編寫自定義插件
對象插件是實現(xiàn)了org.gradle.api.plugins接口的插件,這個接口中只定義個一個簡單的apply方法,想要實現(xiàn)自定義插件就需要去實現(xiàn)org.gradle.api.plugins接口。
Groovy、Java、Kotlin都可以作為實現(xiàn)插件的語言,在本文的示例中,使用Groovy作為實現(xiàn)語言。
在實際工作中我們很少會在build.gradle中編寫自定義插件,這里是為了帶大家寫個最簡單的例子,可以最快最直接的了解什么是自定義插件。
1.1 這里使用AS來編輯,新建一個項目,在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中自定義了一個插件GreetingPlugin,在apply方法中創(chuàng)建一個名稱為GreetingPluginTask的任務(wù)。在AS的Terminal中輸入gradlew.bat GreetingPluginTask來執(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 自定義插件擴展
再舉一個簡單的插件拓展例子,通過插件拓展來配置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是一個Groovy Bean(類似于JavaBean)。注釋1處用于添加拓展插件GreetingPluginPluginExtension到插件列表中,名稱為greeting。注釋2處設(shè)置GreetingPluginPluginExtension的message值。
Terminal中輸入gradlew.bat GreetingPluginTask來執(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工程項目
除了在build.gradle中編寫的自定義插件,還可以將插件的源代碼放在rootProjectDir/buildSrc/src/main/groovy目錄中,Gradle會自動識別來完成編譯和測試。Android Studio會找rootPrjectDir/buildSrc/src/main/groovy目錄下的代碼。
坑:當新建libraray module并命名為buildSrc后會提示Plugin with id'com.android.library' not found.
這是因為buildSrc是Android的保留名稱,只能作為plugin插件使用,我們修改buildSrc的build.gradle文件后就不報錯了。
具體流程如下:
2.1. 首先創(chuàng)建一個名為buildSrc的module,注意,名稱必須為buildSrc
2.2. 然后將其它不需要的文件刪除,新建需要的文件夾和文件,最后的目錄結(jié)構(gòu)如下圖所示:
2.3. 新建對應(yīng)的文件和文件夾之后,工程開始會不認這個buildSrc,我們修改build.gradle:
apply plugin: 'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
}
點擊Sync Now,完了之后發(fā)現(xiàn)groovy文件夾變藍色了
2.4. 在對應(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的名稱就是我們之后要引用這個插件時apply plugin:''引號填入的內(nèi)容)
implementation-class=YolynPlugin
這里的YolynPlugin就是我們創(chuàng)建的YolynPlugin.groovy文件,一定要對應(yīng)上,否則會報找不到的錯誤。
2.6. 在app的gradle中去引用這個插件
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
疑問1
這里有一個疑問,為什么先打印出welcome to YolynPlugin,是因為doLast嗎,怎么解釋?
疑問2
我們再創(chuàng)建一個插件叫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í)行了
疑問3
我們把兩個Plugin中的doLast去掉
我們再在Terminal中輸入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)全部都打印出來了,這是為什么?
- 對于疑問1:
我們看一下官方對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
大致意思是會創(chuàng)建一個給定名字的task放到這個project里面,調(diào)用這個方法相當于調(diào)用這個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.
這樣就能解釋了,確實是因為doLast將任務(wù)添加到project的tasks的list的最后了,所以才最后執(zhí)行。具體還可以查看官方文檔的Project,文檔在gradle安裝目錄的docs里面可以找到。
==疑問二和疑問三是為什么???求解==
日后繼續(xù)研究
再看第三種形式
3. 獨立項目或獨立Module
無論是在build.gradle中編寫自定義插件,還是buildSrc項目中編寫自定義插件,都只能在自己的項目中進行使用。如果想要分享給其他人或者自己用,可以在一個獨立的項目中編寫插件,這個項目會生成一個包含插件類的JAR文件,有了JAR文件就很容易進行分享了。
3.1 創(chuàng)建一個名為YolynPlugin的module
跟上面創(chuàng)建buildSrc一樣,將其它文件刪除,并創(chuàng)建相應(yīng)的文件和文件夾,最終目錄結(jié)構(gòu)如下:
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 將代碼上傳到倉庫或者本地,這里是放到本地
在這個module的build.gradle追加下面內(nèi)容
group='com.example.yolynplugin'
version='1.0.0'
//group和version在后面會用到
uploadArchives {
repositories {
mavenDeployer {
//提交到遠程服務(wù)器:
// repository(url: "http://www.xxx.com/repos") {
// authentication(userName: "admin", password: "admin")
// }
repository(url:uri('../repo'))
}
}
}
上面各個參數(shù)的邏輯意義參考官方文檔:
https://docs.gradle.org/current/dsl/index.html
這里直接將插件上傳到了本項目的根目錄,點擊Build之后在Gradle窗口會看到uploadArchives
點擊uploadArchives會在本地生成插件相關(guān)的文件,比如我的目錄和文件如下圖所示
圖中的YolynPlugin-1.0.0.jar就是我們需要的插件jar包。
3.6 去app下面的module中引用
在build.gradle中追加下面內(nèi)容
apply plugin: 'com.example.yolynplugin'//properties的名字
buildscript {
//repositories這個模塊的內(nèi)容告訴gradle去什么地址下載第三方的庫。
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是版本號
也可以這么寫:
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
三個插件都成功運行
筆記來源于:
1.https://blog.csdn.net/huachao1001/article/details/51810328
2. http://liuwangshu.cn/application/gradle/6-custonplugin.html