天天看點

一篇文章帶你了解Gradle插件的所有建立方式

Gradle中插件可以分為兩類:腳本插件和對象插件。

腳本插件

腳本插件就是一個普通的gradle建構腳本,通過在一個foo.gradle腳本中定義一系列的task,另一個建構腳本bar.gradle通過

apply from:'foo.gradle'

即可引用這個腳本插件。

首先在項目根目錄下建立一個config.gradle檔案,在該檔案中定義所需的task。

一篇文章帶你了解Gradle插件的所有建立方式
//config.gradle
project.task("showConfig") {
     doLast {
        println("$project.name:showConfig")
    }
}
           

然後在需要引用的module的建構腳本中引用

config.gradle

,例如在

app.gradle

中,由于

config.gradle

建立在根目錄下,與app這個子產品平級,是以需要注意路徑問題

../config.gradle

//app.gradle
apply from: '../config.gradle'
           

就是這麼簡單,此時運作gradle建構即可執行showConfig這個task,

garretdeMacBook-Pro:CustomPlugin garretwei$ ./gradlew showConfig
> Task :app:showConfig
app:showConfig
           

對象插件

對象插件是指實作了org.gradle.api.Plugin接口的類。Plugin接口需要實作

void apply(T target)

這個方法。該方法中的泛型指的是此Plugin可以應用到的對象,而我們通常是将其應用到Project對象上。

編寫對象插件主要有三種方式:

  1. 直接在gradle腳本檔案中
  2. 在buildSrc目錄下
  3. 在獨立的項目下

在gradle腳本檔案中

直接在gradle腳本中編寫這個方式是最為簡單的。打開

app.gradle

檔案,在其中編寫一個類實作Plugin接口。

//app.gradle
class CustomPluginInBuildGradle implements Plugin<Project> {
    @Override
    void apply(Project target) {
       target.task('showCustomPluginInBuildGradle'){
            doLast {
                println("task in CustomPluginInBuildGradle")
            }
        }
    }
}
           

然後通過插件類名引用它

//app.gradle
apply plugin: CustomPluginInBuildGradle
           

執行插件中定義的task

garretdeMacBook-Pro:CustomPlugin garretwei$ ./gradlew -q showCustomPluginInBuildGradle
task in CustomPluginInBuildGradle
           

除了直接寫在某個子產品的建構腳本中,我們還可以将插件寫在工程根目錄下的buildSrc目錄下,這樣可以在多個子產品之間複用該插件。

雖然buildSrc是Gradle在項目中配置自定義插件的預設目錄,但它并不是标準的Android工程目錄,是以使用這種方式需要我們事先手動建立一個buildSrc目錄。目錄結構如下:

一篇文章帶你了解Gradle插件的所有建立方式

buildSrc目錄結構

在buildSrc/src/main/groovy目錄下建立自定義plugin,并在build.gradle中引用groovy插件

//  buildSrc/build.gradle
apply plugin: 'groovy'
dependencies {
    compile gradleApi()
    compile localGroovy()
}
           

然後編寫plugin代碼

class CustomPluginInBuildSrc implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('showCustomPluginInBuildSrc') {
            doLast {
                println('task in CustomPluginInBuildSrc')
            }
        }
    }
}
           

由于buildSrc目錄是gradle預設的目錄之一,該目錄下的代碼會在建構是自動編譯打包,并被添加到buildScript中的classpath下,是以不需要任何額外的配置,就可以直接被其他子產品的建構腳本所引用。

注意這裡引用的方式可以是通過類名引用,也可以通過給插件映射一個id,然後通過id引用。

通過類名引用插件的需要使用全限定名,也就是需要帶上包名,或者可以先導入這個插件類,如下

apply plugin: com.gary.plugin.CustomPluginInBuildSrc
           

或者

import com.gary.plugin.CustomPluginInBuildSrc
apply plugin: CustomPluginInBuildSrc
           

通過簡單的id的方式,我們可以隐藏類名等細節,使的引用更加容易。映射方式很簡單,在buildSrc目錄下建立resources/META-INF/gradle-plugins/xxx.properties,這裡的xxx也就是所映射的id,這裡我們假設取名myplugin。具體結構可參考上文buildSrc目錄結構。

myplugin.properties檔案中配置該id所對應的plugin實作類

implementation-class=com.gary.plugin.CustomPluginInBuildSrc
           

此時就可以通過id來引用對于的插件了

//app.gradle
apply plugin: 'myplugin'
           

在獨立工程下

在buildSrc下建立的plugin隻能在該工程下的多個子產品之間複用代碼。如果想要在多個項目之間複用這個插件,我們就需要在一個單獨的工程中編寫插件,将編譯後的jar包上傳maven倉庫。

這裡為了不增加複雜度,我們還是在該工程下建立一個standaloneplugin子產品。隻需要明白我們完全可以在一個獨立的工程下來編寫插件。

一篇文章帶你了解Gradle插件的所有建立方式

standAlonePlugin目錄結構

從目錄結構來看,和buildSrc目錄是一緻的。差別在于buildSrc下的代碼在建構時會自動編譯并被引用。而我們在獨立項目中編寫的插件如果要能正确的被引用到,需要上傳到maven倉庫中,然後顯式地在需要引用的項目中的buildSrcipt中添加對該構件的依賴。

插件代碼

class StandAlonePlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('showStandAlonePlugin') {
            doLast {
                println('task in StandAlonePlugin')
            }
        }
    }
}
           

插件項目建構腳本

apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
    compile gradleApi()
    compile localGroovy()
}
group = 'com.gary.plugin'
version = '1.0.0'
uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}
           

這裡與buildSrc不同的是,我們引用了

apply plugin 'maven'

,通過maven插件,我們可以輕松的配置group,version 以及 uploadArchives的相關屬性,然後執行

./gradlew uploadArchives

這個任務,就可以将構件打包後上傳到maven倉庫了。同樣為了示例簡單,我們上傳到一個本地倉庫

repository(url: uri('../repo'))

中。

上傳之後就可以在項目根目錄下找到

repo

這個目錄了。最後我們通過給根目錄下的build.gradle配置buildScript的classpath,就可以引用這個插件了。注意,classpath的格式為

group:artifact:version

buildscript {
    repositories {
        maven {
            url uri('repo')
        }
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.1'
        classpath 'com.gary.plugin:standaloneplugin:1.0.0'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
           

引用插件

//app.gradle
apply plugin: 'standAlonePlugin'
           

執行StandAlonePlugin中定義的任務

./gradlew -q showStandAlonePlugin
task in StandAlonePlugin
           

總結

  • 插件分為腳本插件和對象插件。
  • 腳本插件通過

    apply from: 'foo.gradle'

    引用。
  • 對象插件可以在目前建構腳本下直接編寫,也可以在buildSrc目錄下編寫,還可以在完全獨立的項目中編寫,通過插件類名或是id引用。

    apply plugin: ClassName

    apply plugin:'pluginid'

本文所編寫的插件代碼隻是起到簡單說明,主要介紹插件編寫方式。實際插件編寫過程中需要用到的Extension,以及Project和Gradle相關的生命周期方法等api并未涉及。相關知識點可以參考本系列文章中的【實戰,從0到1完成一款Gradle插件】。

最後

更多Android進階技術,面試資料系統整理分享,職業生涯規劃,産品,思維,行業觀察,談天說地。可以加Android架構師群;701740775。

繼續閱讀