Gradle核心思想(五)通俗易懂的Gradle外掛講解

劉望舒發表於2019-04-08

本文首發於微信公眾號「劉望舒」

關聯文章
Gradle核心思想(一)為什麼現在要用Gradle?
Gradle核心思想(二)Gradle入門前奏
Gradle核心思想(三)Groovy快速入門指南
Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper
Gradle核心思想(五)通俗易懂的Gradle外掛講解

前言

在本系列的前作中,我們學習了為什麼要用Gradle、Gradle的入門基礎和Groovy的基礎,這些文章為Gradle的入門打下了基礎,這一篇我們要來學習Gradle的外掛。

1.Gradle外掛概述

說到Gradle外掛前,我們先要了解下什麼是外掛。在Android進階三部曲第二部《Android進階解密》一書中,我為了講解外掛化的原理,講解了什麼是外掛,我們先來看看下面這張圖。

Gradle核心思想(五)通俗易懂的Gradle外掛講解
可以看到初始的機器人只有照相、地圖、瀏覽器、計算機等功能,這顯然是比較乏味的,我們可以給這個機器人安裝很多其他的應用,使它提供更多的功能,如下圖所示

Gradle核心思想(五)通俗易懂的Gradle外掛講解

我們給這個機器人安裝了很多應用,這些應用不僅覆蓋了人的衣食住行還提供了娛樂功能,我們可以玩遊戲、聽音樂和購物等等,機器人也得到了極大的提升,能夠購為人類提供更多的服務。這些安裝的應用可以理解為外掛,這個外掛可以自由的進行插拔,比如我們需要玩遊戲時可以安裝王者榮耀,如果不好玩就把它解除安裝掉。這麼說來其實Android、iOS、Mac等作業系統採用的都是這種思想,而Gradle也是如此。 Gradle本身和初始的機器人一樣,只是提供了基本的核心功能,其他的特性比如編譯Java原始碼的能力,編譯Android工程的能力等等就需要通過外掛來實現了。本篇文章主要說的是Gradle外掛,而不是Android Gradle外掛。

2.應用Gradle外掛

要想應用外掛,主要有兩個步驟,一是解析外掛,二是把外掛應用到專案中,應用外掛通過 Project.apply() 方法來完成。 在Gradle中一般有兩種型別的外掛,分別叫做指令碼外掛和物件外掛。指令碼外掛是額外的構建指令碼,它會進一步配置構建,可以把它理解為一個普通的build.gradle。物件外掛又叫做二進位制外掛,是實現了Plugin介面的類,下面分別介紹如何使用它們。

2.1 指令碼外掛

在上一篇文章Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper的例子基礎上,定義一個other.gradle,例子的目錄結構是如下圖所示。

Gradle核心思想(五)通俗易懂的Gradle外掛講解

other.gradle

ext{
verson='1.0'
url='http://liuwangshu.cn'
}
複製程式碼

這實際上不算是一個真正的指令碼外掛,就是一個簡單的指令碼,主要是用於演示指令碼外掛是如何被應用的。我們在build.gradle中來應用這個外掛: build.gradle

apply from: 'other.gradle'
task test {
    doLast {
        println "版本為:${verson},地址為:${url}"
    }
}
複製程式碼

apply是Gradle project中提供的方法,用於配置專案中的外掛。執行gradlew.bat test,會列印出想要的結果。

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相關的知識,脫離了本文的討論範圍,具體的請見後續的Gradle for Android系列。

2.3 外掛DSL

Gradle的特性有四種狀態,分別是Internal、Incubating、Public、Deprecated,外掛DSL屬於Incubating狀態(孵化狀態)。 這也導致外掛DSL的特性在將來的Gradle版本中可能會發生變化,直到它不再孵化為止。 使用Java外掛可以這麼寫: build.gradle

plugins {
    id 'java'
}
複製程式碼

很簡潔,當然這是使用內部外掛,如果外部外掛被託管在https://plugins.gradle.org/,也可以這樣寫: build.gradle

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也可以),用IntelliJ來開啟2.1小節的例子,改寫build.gradle檔案: build.gradle

apply plugin:CustomPlugin
class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('CustomPluginTask') {
            doLast {
                println "自定義外掛"
            }
        }
    }
}
複製程式碼

在build.gradle中自定義了一個外掛CustomPlugin,在apply方法中建立一個名稱為CustomPluginTask的任務。在IntelliJ的Terminal中輸入gradlew.bat CustomPluginTask來執行CustomPluginTask任務。

Gradle核心思想(五)通俗易懂的Gradle外掛講解

這個例子只能在自己專案中使用,而且比較簡單,更復雜的由於篇幅原因會在本系列的下一篇文章進行介紹。

3.Gradle外掛的作用和好處

Gradle外掛可以做什麼呢?主要有以下的幾點

  • 為專案配置依賴。
  • 為專案配置約定,比如約定原始碼的存放位置。
  • 為專案新增任務,完成測試、編譯、打包等任務。
  • 為專案中的核心物件和其他外掛的物件新增擴充型別。

使用Gradle外掛主要有以下的好處:

  • 重用和減少維護在多個專案類似的邏輯的開銷。
  • 更高程度的模組化。
  • 封裝必要的邏輯,並允許構建指令碼儘可能是宣告性地。

總結

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


不僅分享大前端、Java、Android、跨平臺等技術,還有大廠乾貨和程式設計師成長類文章。

Gradle核心思想(五)通俗易懂的Gradle外掛講解

相關文章