上一篇咱們介紹了 gradle 插件相關的概念,沒看的同窗能夠點擊這裏查看,這一篇讓咱們結合例子來看看如何一步步建立一個 gradle 插件,並在 Android 項目中使用。java
工欲善其事必先利其器,要開發 gradle 插件得先決定用什麼開發環境。我本身使用過 Intellij IDEA 和 AndroidStudio 來開發,由於 AndroidStudio 是基於 Intellij 改的,因此區別不是很大。android
但就我我的的偏好來講更偏向於 Intellij,由於 AndroidStudio 是專門用來開發 Android 的,有不少配套的調試按鈕,若是用來開發一個純的 gradle 插件項目就會很彆扭,因此個人判斷原則是:api
gradle 插件比較主流的開發語言是 groovy,由於 gradle 就是用 groovy 寫的。經過查看第三方寫的 gradle 插件代碼發現大部分也是用 groovy 寫的。bash
除了 groovy 還能夠用來開發 gradle 插件的語言有:網絡
由於 groovy 是基於 jvm 的,因此一樣基於 jvm 的也能夠用來寫 gradle 插件。但 java 和 kotlin 是靜態語言,意味着須要不停地判斷類型和強轉,相比之下,groovy 做爲動態語言就沒有這個問題。因此本文後續的插件代碼都是 groovy 寫的。app
具體開發以前讓咱們先來看看要開發的 gradle 插件要知足什麼需求。jvm
實現一個插件,名字叫 io.helloworld.myplugin
,須要實現下面的功能:maven
myTask
。打開 Intellij IDEA,按 file -> new -> project 建立一個新項目。在 「new project」對話框左邊選擇 gradle,右邊的 「Additional Libraries and Frameworks」只選擇 Groovy:ide
下一個界面選擇表明你這個插件包的 groupId 和 ArtifactId,例如 io.helloworld.robot
和 gradletools
,版本號能夠保持默認不變 1.0-SNAPSHOT
post
groupId、artifactId 和 version 構成了咱們這個插件包的標識 Id,另外一個項目若是想使用咱們這個插件時,就須要經過這個 Id 來聲明依賴。
而後點 「next」-> 「finish」,項目結構大概像下面這樣:
由於要用到 gradle 的依賴,因此須要在項目 build.gradle 腳本文件中加一條 gradle 的依賴:
dependencies {
implementation gradleApi()
...
}
複製代碼
建立項目時,IDE 會默認添加上 groovy 的依賴:
implementation 'org.codehaus.groovy:groovy-all:2.3.11' 複製代碼
爲了防止出現 groovy 版本不一致的問題,這裏的依賴最好換成下面這樣,讓 gradle 自動去獲取本地的 groovy 版本。
implementation localGroovy() 複製代碼
而後點一下 gradle 的同步按鈕,保證 IDE 能引用到對應的類。
在 groovy 文件夾下建立包 io.helloworld.robot
,和前面設置的 groupId 保持一致。在這個包下建立一個 groovy 類 MyPlugin
,代碼以下:
package io.helloworld.robot
import org.gradle.api.Plugin
import org.gradle.api.Project
class MyPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println("beginning of plugin 'MyPlugin'")
}
}
複製代碼
能夠看到 MyPlugin
實現了 Plugin<Project>
的接口,而這個接口有一個方法 apply(Project project)
,猜想當咱們這個插件在 build.gradle
中應用時,這個方法會被調用,咱們在這個方法中加上一行打印調試信息的代碼。
這裏建立的插件是給
build.gradle
用的,因此Plugin
的泛型類型是Project
,若是給settings.gradle
用的話,泛型類型應該是Settings
。
如今咱們的插件已經建立好了(雖然很簡陋),那怎樣才能讓 Android 項目使用到它呢?還須要再作兩件事:建立插件的聲明文件和將包含插件的軟件包發佈到 maven 倉庫。
建立插件的聲明文件
須要在 resources 文件夾下建立文件夾 META-INF/gradle-plugins,全部插件的聲明文件都要放在這個目錄下:
插件的聲明文件都是後綴爲 properties
的配置文件,文件名就是插件的名字,例如這裏的插件名字就是 io.helloworld.myplugin
。在文件中經過 implementation-class
的值關聯到上面建立的插件類 MyPlugin
:
implementation-class=io.helloworld.robot.MyPlugin
複製代碼
發佈到 maven 倉庫
由於 maven 倉庫不是這篇文章的重點,因此簡單起見,這裏將包含插件的軟件包發佈到本地倉庫。
要發佈到本地倉庫,build.gradle
須要加上下面這些代碼:
apply plugin: 'maven-publish'
publishing {
publications {
mavenPub(MavenPublication) {
// 這一行表示將 jar 包包含在要發佈的組件中
from components.java
// 描述性信息
pom {
name = 'Robot MyPlugin'
description = 'This is a test project for gradle plugin.'
url = 'http://www.helloworld.com'
}
}
}
repositories {
maven {
// 本地 repo 地址,這裏寫上大家電腦上本身的地址
url = '/Users/zhanglei/projects/repo'
}
}
}
複製代碼
這裏使用 maven-publish
插件來發布到 maven 倉庫,其實發布到網絡上也是相似的,將上面代碼的 url
改爲網絡地址,再加上用戶名/密碼就能夠了。
改好 build.gradle
後點一下 gradle 的同步按鈕,在 gradle 窗口的 Tasks 條目下就會看到 publishing 的 Task 分組,其中能夠找到「publish」Task:
雙擊執行這個 Task 來發布組件,執行結束後在上述本地倉庫的地址下能夠看到組件已經發布成功:
OK,全部的準備工做都作完了,如今可使用插件了。
在 Android 項目中使用插件
由於咱們的插件是配置 Android 相關信息,因此要在 application 類型的 module 下使用。在 AndroidStudio 中打開 module 下的 build.gradle
文件,加上下面的代碼:
// 使用插件
apply plugin: 'io.helloworld.myplugin'
buildscript {
repositories {
// 聲明本地 repo 的地址
maven {
url '/Users/zhanglei/projects/repo'
}
}
dependencies {
// 聲明依賴咱們上面發佈到本地 maven 倉庫的軟件包
classpath 'io.helloworld.robot:gradletools:1.0-SNAPSHOT'
}
}
複製代碼
由於插件發佈在本地倉庫中,因此要在 buildscript.repositories 中聲明一下倉庫地址。而後在 AndroidStudio 中同步下 gradle 就能夠看到咱們剛纔寫在 apply()
中的調試代碼輸出的 log:
AndroidStudio 中同步 gradle 和 Intellij 中稍微有點不同:點下面這個按鈕:
好的,咱們如今把開發插件到使用插件這條路調通了,接下來咱們在插件中完成上面說的「插件需求」,先來看看第一個:
實現插件功能一:進行 Android 自動配置
- minSdkVersion 設置爲 21
- targetSdkVersion 設置爲 26
- compileSdkVersion 設置爲 29
- buildToolsVersion 設置爲 29.0.2
在 Intellij 中打開 MyPlugin 類,在 apply()
方法中加上下面這段代碼:
project.extensions.findByName('android').with {
getProperty('defaultConfig').with {
setProperty('minSdkVersion', 21)
setProperty('targetSdkVersion', 26)
}
setProperty('compileSdkVersion', 29)
setProperty('buildToolsVersion', '29.0.2')
}
複製代碼
而後發佈到本地倉庫,而後在 AndroidStudio 中同步下 gradle,這就至關於在 build.gradle
中寫了:
android {
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
}
compileSdkVersion 29
buildToolsVersion '29.0.2'
}
複製代碼
第一個需求完成了,接下來看一下第二個需求。
實現插件功能二:註冊一個 Task myTask
打開 MyPlugin
,在 apply()
方法中加上下面這段代碼:
project.task('myTask') {
group 'helloworld'
description 'This is a task named myTask, created in myPlugin'
doFirst {
println("run in myTask it $it")
}
}
複製代碼
這裏建立了一個名叫 myTask
的 Task,並設置了 group、description 和它的運行代碼。和上面同樣,將插件發佈到本地倉庫,並同步 Android 項目的 gradle。能夠看到 Android 項目中已經存在 myTask
Task:
到這裏一個擁有基本功能的 gradle 插件就開發好了,若是想繼續擴展這個插件的功能,就繼續在 apply()
方法裏添加代碼。由於 apply()
方法的參數是 project,因此這裏能夠實現 build.gradle
中的全部能力。你也能夠在這個項目中開發一個新的插件,放一些特殊的 gradle 處理邏輯。
關於 gradle 插件開發就簡單介紹到這裏,因爲我也是邊開發邊學習,不免有一些不對的地方,歡迎你們評論指正。