筆記來源于以下文章:
http://liuwangshu.cn/application/gradle/5-plugins.html
前面我們學習了為什么要用Gradle、Gradle的入門基礎和Groovy的基礎,這些文章為Gradle的入門打下了基礎,這一篇我們要來學習Gradle的插件。
1. Gradle插件概述
說到Gradle插件前,我們先要了解下什么是插件。我們先來看看下面這張圖。
可以看到初始的機器人只有照相、地圖、瀏覽器、計算機等功能,這顯然是比較乏味的,我們可以給這個機器人安裝很多其他的應用,使它提供更多的功能,如下圖所示
我們給這個機器人安裝了很多應用,這些應用不僅覆蓋了人的衣食住行還提供了娛樂功能,我們可以玩游戲、聽音樂和購物等等,機器人也得到了極大的提升,能夠購為人類提供更多的服務。這些安裝的應用可以理解為插件,這個插件可以自由的進行插拔,比如我們需要玩游戲時可以安裝王者榮耀,如果不好玩就把它卸載掉。這么說來其實Android、iOS、Mac等操作系統采用的都是這種思想,而Gradle也是如此。
Gradle本身和初始的機器人一樣,只是提供了基本的核心功能,其他的特性比如編譯Java源碼的能力,編譯Android工程的能力等等就需要通過插件來實現了。本篇文章主要說的是Gradle插件,而不是Android Gradle插件。
2. 應用Gradle插件
想要應用插件,主要有兩個步驟。一是解析插件,二是把插件應用到項目中,應用插件通過Project.apply()方法來完成。
在Gradle中一般有兩種類型的插件,分別叫做腳本插件和對象插件。腳本插件是額外的構建腳本,它會進一步配置構建,可以把它理解為一個普通的build.gradle。對象插件又叫做二進制插件,是實現了Plugin接口的類,下面分別介紹如何使用它們。
2.1 插件腳本
在上一篇Gradle Wrapper的例子基礎上,定義一個other.gradle,例子的目錄結構是如下圖所示:
ext{
version='1.0'
url="https://www.baidu.com"
}
這里先簡單講一下這個ext對象在這兒的作用,ext在這起到保存值得作用,在另一個gradle中apply后就可以直接引用這個ext存儲的值。
ext對象還可以進行gradle的復用,比方說another.gradle內容如下:
task hello{
doLast{
println 'hello from other script'
}
}
def showMyName(){
'i am a boy'
}
ext{
showName = showMyName()
}
再apply別的gradle中就可以節省別的gradle的代碼,關于ext就暫時講這么多,繼續往下。
這個ext的屬性就類似于我們的錢包一樣,獨立屬于gradle與project對象。我們可以往這個ext對象里面放置屬性。
這里的這實際上不算是一個真正的腳本插件,就是一個簡單的腳本,主要是用于演示腳本插件是如何被應用的。我們在build.gradle中來應用這個插件:
build.gradle
apply from: 'other.gradle'
task test {
doLast {
println "版本為:${version},地址為:${url}"
}
}
apply是Gradle project中提供的方法,用于配置項目中的插件。執行gradlew.bat test,會打印出想要的結果。
PS D:\DevelopSoftWare_Location\Gradle\gradle_demo> gradle -q test
版本為:unspecified,地址為:https://www.baidu.com
PS D:\DevelopSoftWare_Location\Gradle\gradle_demo>
2.2 對象插件
我們知道對象插件就是實現了org.gradle.api.plugins<Project>接口的插件,對象插件可以分為內部插件和第三方插件。
2.2.1 內部插件
如果我們想要應用Java插件可以這么寫:
build.gradle
apply plugin: org.gradle.api.plugins.JavaPlugin
Gradle默認就導入了org.gradle.api.plugins包,因此我們也可以去掉包名:
apply plugin: JavaPlugin
實現了org.gradle.api.plugins接口的插件會有pulginid,使用pulginid是最簡潔、最常用的方式:
apply plugin:'java'
Gradle的發行包中有大量的插件,這些插件有很多類型,比如語言插件、集成插件、軟件開發插件等等,比方說我們想向項目中添加c++源代碼編譯功能,可以這么寫:
apply plugin:'cpp'
2.2.2 第三方插件
第三方的對象插件通常是jar文件,要想讓構建腳本知道第三方插件的存在,需要使用buildscrip來設置。
buildscript {
repositories {
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath "com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4"
}
}
apply plugin: "com.jfrog.bintray"
在buildscrip中來定義插件所在的原始倉庫的插件和依賴,再通過apply方法配置就可以了。
Android Gradle插件也屬于第三方插件,如果我們想引入Android Gradle插件,可以這么寫:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
}
}
apply plugin: 'com.android.application'
這樣我們就可以使用Android Gradle插件,通過apply方法來使用App工程插件,這樣項目會編譯成為一個apk,這里涉及了Android相關的知識,脫離了本文的討論范圍,在這先簡單介紹一下
- buildscript{}這個是基礎配置,所有的子模塊都會讀取到這個配置里面的內容,當構建開始的時候,就開始讀取這個buildscript{}里面的內容。
- repositories{}這個模塊的內容告訴gradle去什么地址下載第三方的庫。
- jcenter()代表 https://bintray.com/bintray/jcenter
- mavenCentral() 代表使用maven的服務器 https://search.maven.org/
2.3 插件DSL
Gradle的特性有四種狀態,分別是Internal、Incubating、Public、Deprecated(棄用),插件DSL屬于Incubating狀態(孵化狀態)。
這也導致插件DSL的特性在將來的Gradle版本中可能會發生變化,直到它不再孵化為止。
使用Java插件可以這么寫:
build.gradle
plugin{
id 'java'
}
很簡潔,當然這是使用內部插件,如果外部插件被托管在https://plugins.gradle.org/,也可以這樣寫:
plugins {
id "com.jfrog.bintray" version "1.8.4"
}
不需要再配置buildscript了,直接配置plugins來使用插件。
2.4 自定義對象插件
對象插件是實現了org.gradle.api.plugins<Project>接口的插件,這個接口中只定義個一個簡單的apply方法,想要自定義插件就需要去實現org.gradle.api.plugins<Project>接口。
來實現一個簡單的自定義插件,為了方便測試,不再采用文本編輯,而是使用IntelliJ來編輯(AS也可以),我這里是用AS,改寫build.gradle文件:
// Apply the plugin
apply plugin: GreetingPlugin
class GreetingPlugin implements Plugin<Project> {
void apply(Project project) {
project.task('hello') {
doLast {
println 'Hello from the GreetingPlugin'
}
}
}
}
在build.gradle中自定義了一個插件GreetingPlugin,在apply方法中創建一個名稱為hello的任務。在AS的Terminal中輸入gradlew.bat hello來執行hello任務。
D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradle>gradlew hello
> Task :app:hello
Hello from the GreetingPlugin
BUILD SUCCESSFUL in 1s
1 actionable task: 1 executed
這個例子只能在自己項目中使用,而且比較簡單
3. 插件的作用和好處
Gradle插件可以做什么呢?主要有以下幾點:
- 為項目配置依賴。
- 為項目配置約定,比如約定源代碼的存放位置。
- 為項目添加任務,完成測試、編譯、打包等任務。
- 為項目中的核心對象和其他插件的對象添加拓展類型。
使用Gradle插件主要有以下幾點好處:
- 重用和減少維護在多個項目類似的邏輯的開銷。
- 更高程度的模塊化。
- 封裝必要的邏輯,并允許構建腳本盡可能是聲明性地。
最后
本篇的文章篇幅不長,主要是沒有更多的介紹自定義對象插件??赡苡械耐瑢W發現了,本系列的Gradle的文章都盡量不和Android和AS有所關聯,為的是擺脫Android的束縛,Gradle本身就是一門技術,當我們了解了Gradle的核心思想后,再去學習Android Gradle時會有豁然開朗的效果