Gradle之Gradle插件講解(五)

筆記來源於以下文章:
http://liuwangshu.cn/application/gradle/5-plugins.html

前面我們學習了爲什麼要用Gradle、Gradle的入門基礎和Groovy的基礎,這些文章爲Gradle的入門打下了基礎,這一篇我們要來學習Gradle的插件。

1. Gradle插件概述

說到Gradle插件前,我們先要了解下什麼是插件。我們先來看看下面這張圖。

image

可以看到初始的機器人只有照相、地圖、瀏覽器、計算機等功能,這顯然是比較乏味的,我們可以給這個機器人安裝很多其他的應用,使它提供更多的功能,如下圖所示
image

我們給這個機器人安裝了很多應用,這些應用不僅覆蓋了人的衣食住行還提供了娛樂功能,我們可以玩遊戲、聽音樂和購物等等,機器人也得到了極大的提升,能夠購爲人類提供更多的服務。這些安裝的應用可以理解爲插件,這個插件可以自由的進行插拔,比如我們需要玩遊戲時可以安裝王者榮耀,如果不好玩就把它卸載掉。這麼說來其實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插件可以做什麼呢?主要有以下幾點:

  1. 爲項目配置依賴。
  2. 爲項目配置約定,比如約定源代碼的存放位置。
  3. 爲項目添加任務,完成測試、編譯、打包等任務。
  4. 爲項目中的核心對象和其他插件的對象添加拓展類型。

使用Gradle插件主要有以下幾點好處:

  1. 重用和減少維護在多個項目類似的邏輯的開銷。
  2. 更高程度的模塊化。
  3. 封裝必要的邏輯,並允許構建腳本儘可能是聲明性地。

最後

本篇的文章篇幅不長,主要是沒有更多的介紹自定義對象插件。可能有的同學發現了,本系列的Gradle的文章都儘量不和Android和AS有所關聯,爲的是擺脫Android的束縛,Gradle本身就是一門技術,當我們瞭解了Gradle的核心思想後,再去學習Android Gradle時會有豁然開朗的效果

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章