「Gradle」| 手把手自定義 Gradle 插件 | 七日打卡

點贊關注,再也不迷路,你的支持對我意義重大!html

🔥 Hi,我是醜醜。本文 GitHub · Android-NoteBook 已收錄,這裏有 Android 進階成長路線筆記 & 博客,歡迎跟着彭醜醜一塊兒成長。(聯繫方式在 GitHub)android


目錄


1. 前置知識

這篇文章的內容會涉及如下前置 / 相關知識,貼心的我都幫你準備好了,請享用~git


2. Gradle 插件概述

2.1 什麼是 Gradle?什麼是 Gradle 插件?

Gradle 插件的本質就是抽取高度模塊化的邏輯,以便更高效地進行復用。 Gradle 和 Gradle 插件是兩個概念,在前面的文章裏,你已經瞭解過 Gradle 的核心工做原理。簡單來講,Gradle 只是提供了一個構建流程。而其餘可複用的 Task(例如編譯 Java 工程、編譯 Android 工程等),是經過應用 Gradle 插件來獲取的。網絡

  • Gradle: 構建工具,提供核心構建流程
  • Gradle 插件: 本質上是可複用的 task,依賴於 Gradle 環境

2.2 插件類型

Gradle 插件分爲兩大類:腳本插件 & 對象插件閉包

  • 腳本插件: 一個腳本插件和一個普通的 build.gradle 文件沒什麼區別,雖然簡單,但它是模塊化的基礎。腳本能夠存在本地,也能夠存在網絡上,只須要提供腳本的相對路徑或者 URL,例如:
apply other.gradle
複製代碼
  • 對象插件: 編寫一個對象插件的最低要求是提供一個 org.gradle.api.Plugin 接口的實現類,這個接口只要一個Plugin#apply(Project)方法。

Plugin.Javaapp

package org.gradle.api;

public interface Plugin<T> {
    void apply(T var1);
}
複製代碼

2.3 應用插件

在 build.gradle 文件中,能夠使用 apply 方法來應用插件,有兩種語法:maven

  • 語法 1:
apply plugin 'groovy'
複製代碼
  • 語法 2:
plugins {
    id 'groovy'
    id 'maven'
}
複製代碼

這裏的 id 是插件的簡短名稱,是在插件中resources/META-INF/gradle-plugins/[id].properties文件的文件名決定的。

注意: 在一個 build.gradle 中不要同時使用這兩種語法。


3. 自定義插件

這一節,咱們開始討論自定義插件的細節。前面提到 Gradle 插件分爲腳本插件 & 對象插件,由於腳本插件比較簡單,同時使用較少,因此咱們以討論對象插件爲主。

踩坑: 筆者在學習 Gradle 插件時踩了一個深坑,即:setting.gradle 中若是存在rootProjet.name='項目名',那麼在應用插件並 sync 後會報錯:

An exception occurred applying plugin request [id 'hello'] > Failed to apply plugin [id 'hello']  > No such property: project for class HelloPlugin

刪除rootProjet.name='項目名'就不會報這個問題,緣由未查。

3.1 步驟一:建立插件項目

首先,咱們須要建立一個單獨存放插件代碼的 Module。Module 的命名能夠是任意的,不過卻是有一個特殊的 Module 名 —— 「buildSrc」。要點以下:

  • 一、這個目錄能夠被自動識別爲 Module,不須要在 setting.gradle 中進行包含;
  • 二、在構建時自動編譯打包並添加到 buildScript 中的 classpath 下,不須要手動發佈插件;
  • 三、buildSrc 編譯時間先於工程編譯。

3.2 步驟二:初始化插件項目

咱們對新建的插件項目進行如下操做:

  • 一、(可選,若是你的項目中用不到 Java 代碼)移除 Java 文件夾;
  • 二、(必選)添加 groovy 文件夾,用於存放插件代碼;
  • 三、(必選)添加 resources 文件夾,用於配置插件描述符;
  • 四、(必選)修改 build.gradle 內容。

下面介紹下第 三、4 步:

3.2.1 配置插件描述符

你須要新建一個*.properties文件,存放路徑爲:

main
├── groovy
├── resources 
    ├── META-INF
        ├── gradle-plugins
            ├── *.properties
複製代碼

提示: 你能夠經過 sourceSets {} 閉包方法來設置 resources 文件夾的位置。

這裏只須要記住兩個要點:

  • 一、*.properties 文件名是插件的剪短名稱(id),用於應用插件。例如:
com.xurui.plugin.properties 
複製代碼
  • 二、*.properties 文件內容配置了插件實現類的映射,須要使用implementation-class來指定插件實習類的全限定類名。例如:
implementation-class=com.xurui.plugin.HelloPlugin 
複製代碼

3.2.2 修改 build.gradle 內容

插件 build.gradle

plugins {
    id 'groovy' // (必選)用於實現插件
    id 'maven' // 用於發佈插件
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}

// 設置源文件路徑
sourceSets {
    main {
        groovy {
            srcDir 'src/main/groovy'
        }

        resources {
            srcDir 'src/main/resources'
        }
    }
}
複製代碼

應用 Groovy 插件,並將 Gradle API 添加爲編譯時依賴項。在 External Libraries 中生成三個 jar 文件:

3.3 步驟三:實現插件

在 groovy 文件夾下實現插件的主題邏輯,例如:

com.xurui.plugin.HelloPlugin.groovy

class HelloPlugin implements Plugin<Project  > {
    @Override
    void apply(Project target) {
        println "自定義插件"
    }
}
複製代碼

提示: 文件後綴使用.groovy

3.4 步驟四:應用插件

在 build.gradle 文件中,能夠使用 apply 方法來應用插件,有兩種語法。例如:

  • 語法 1:
apply plugin 'com.xurui.plugin'
apply plugin 'com.android.application'
複製代碼
  • 語法 2:
plugins {
    id 'com.xurui.plugin'
    id 'com.android.application'
}
複製代碼

應用插件後,從構建過程輸出(Build Output)就能夠看到咱們的插件生效了:

Executing tasks: [:app:generateDebugSources] in project  E:\workspace\...

【初始化階段結束】,總共耗時:9ms

> Configure project :app
自定義插件
【配置階段結束】,總耗時:1864ms

> Task :app:preBuild UP-TO-DATE
> Task :app:preDebugBuild UP-TO-DATE
> Task :app:checkDebugManifest UP-TO-DATE
> Task :app:compileDebugAidl NO-SOURCE
...
> Task :app:assembleDebug
【執行階段結束】,總耗時:141ms

BUILD SUCCESSFUL in 2s
4 actionable tasks: 4 up-to-date
複製代碼

4. 發佈 & 依賴插件

發佈插件有兩種選擇,這兩種選擇其實無非是發佈的地址不一樣:

  • 發佈到本地倉庫;
  • 發佈到遠程倉庫。

4.1 插件的屬性

發佈的插件須要配置三個屬性,這三個屬性共同造成了插件的惟一表示:

插件屬性 描述
groupId 組織 / 公司名稱
artifactId 項目 / 模塊名稱
version 項目 / 模塊的當前版本號

4.2 配置插件屬性

咱們使用 mavenDeployer 插件 來發布倉庫,你須要在插件 build.gradle 中增長如下配置:

插件 build.gradle

plugins {
    id 'groovy' // (必選)用於實現插件
    id 'maven' // (mavenDeployer 插件)用於發佈插件
}

...

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo')) // 插件的輸出路徑
            pom.groupId = 'xurui_groupId'
            pom.artifactId = 'xurui_artifactId'
            pom.version = '1.0.0'
        }
    }
}
複製代碼

若是須要發佈到遠程倉庫,只須要修改 repository url 地址,例如:

repository(url: RELEASE_URL) {
    authentication(userName: "xurui", password: "xxx")
}
複製代碼

4.3 發佈插件

隨後,執行gradlew uploadArchives命令(注意相對路徑)來執行這個 uploadArchives task,實現插件發佈。也能夠使用 Gradle window 快速執行:

發佈完成後在指定路徑下就會生成插件文件:

4.4 依賴插件

提示: 若是在 buildSrc 目錄下實現插件,就不要手動添加依賴了。Gradle 會自動將 buildSrc 構建產物加入到 classpath。

在須要依賴插件的項目裏,咱們須要添加插件到 classpath 中。例如:

項目根 build.gradle

buildscript {
    repositories {
        google()
        jcenter()
        maven { url uri('./repo') }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.5.3'
        classpath 'xurui_groupId:xurui_artifactId:1.0.0'
    }
}

allprojects {
    repositories {
        google()
        jcenter()

    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}
複製代碼

其中 xurui_groupId 是 group,xurui_artifactId 是 artifactId,1.0.0 是版本號,也能夠用這種語法:

dependencies {
     classpath group: 'xurui_groupId ', name: 'xurui_artifactId ', version: '1.0.0'
 }
複製代碼

4.5 應用插件

完成這一步,就能夠順利應用插件了:

項目 build.gradle

plugins {
    id 'com.xurui.plugin'
    id  'com.android.application'
}
複製代碼

5. 自定義 Extension 與 Task

Editting...


6. 總結

  • Gradle 是構建工具,提供核心構建流程,而 Gradle 插件 本質上是可複用的 task,依賴於 Gradle 環境;
  • 插件類型分爲腳本插件 & 對象插件,對象插件使用比較多;
  • 這篇文章主要是手把手帶你完成自定義插件的步驟,但願能幫助你避坑。在後面的文章裏,我將和你一塊兒使用自定義 Gradle 插件完成實戰功能。請關注~

參考資料


創做不易,你的「三連」是醜醜最大的動力,咱們下次見!

相關文章
相關標籤/搜索