Gradle自定義插件以及發布方法

前言

我們平常在進行Android開發時,都會使用 Gradle 來進行項目配置,通常在對應的module:app的build.gradle中,在最上面的一句話一般都為:

apply plugin: 'com.android.application'

這句話就是用來加載gradle的android開發插件,然后,我們就可以使用該插件提供的配置方法進行Android項目的配置了,即如下所示:

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.1"
    defaultConfig {
        applicationId "com.yn.gradleplugintest"
        minSdkVersion 23
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

更多 android 插件配置詳情,請查看:Android Plugin DSL Reference

簡單來講,Gradle插件允許我們做一些額外的擴展工作,比如我想在module每次build完成后,把生成的jar/aar移動到另一個項目的libs文件內,相當于動態更新庫文件······
其實像上面這種操作用 Gradletask 就可以完成,但是使用 task 的一個弊端就是沒辦法做到復用,而使用 Gradle 你就能在任何項目,任何模塊中使用同一套邏輯功能,甚至于你還能對不同的模塊進行動態化的個性配置,只要插件代碼支持即可。

更多 Gradle 使用方法,請查看官網:Gradle User Guide

自定義插件

上面我們說了自定義插件的諸多好處,那么,究竟該如何進行 Gradle 自定義插件的編寫呢 ?
其實,自定義插件基于源碼放置可以分為3種:

  • 第一種:Build script
    這種插件腳本的源碼放置在模塊內的 build.gradle 中,好處就是插件腳本會被自動編譯并添加進模塊的 classpath 中,我們完全不用做任何事情。但是,這種插件腳本只能在聲明的這個 build.gradle 中使用,其他模塊是沒辦法復用這個插件的。
//app build.gradle
apply plugin: BuildScriptPlugin

class BuildScriptPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('hello') {
            group = "test"
            description = "gradle build script demo,shares only in this build.gradle"
            doLast {
                println "Hello from the BuildScriptPlugin"
            }
        }
    }
}

如上面這個插件 GreetingPlugin,我們是在 appbuild.gradle 中聲明定義的,然后,在控制臺運行下: gradle app:tasks,或者直接看Android Studio的Gradle窗口,可以看到如下結果:

Build script

可以看到,只有我們聲明編寫的 app 中成功添加了一個 task:hello(根目錄也會同時添加進這個插件功能),然后,你在工程其他 build.gradleapply plugin: GreetingPlugin 是無法成功的,因為這種插件對其他模塊是不可見的。

所以,Build script 這種插件其實跟直接定義一個 task 沒有多大區別。

  • 第二種:buildSrc project
    這種插件腳本要求源碼放置在 rootProjectDir/buildSrc/src/main/groovy目錄內(也就是工程根目錄下創建 buildSrc 目錄),然后 Gradle 就會自動編譯和測試這個插件,同時,這種方法創建的插件對工程內的所有模塊都是可以使用的。

buildSrc project

從上圖可以看到,我們在模塊 app 中成功加載了插件,所以,使用 buildSrc project 這種插件腳本方法就使得我們創建了一個工程插件。

在你工程只需擴展本工程額外功能,不需與其他工程或者其他開發者進行共用時,buildSrc project 這種插件開發或許是個不錯的選擇。

  • 第三種:Standalone project
    這種方法就是使用單獨的一個工程/模塊創建我們的 Gradle 插件,這種方法會構建和發表一個JAR文件,可以提供給多工程構建和其他開發者共同使用。通常來說,JAR文件內可能包含有一些自定義的插件腳本,或者是由一些相關的 task 類組合成的一個庫,獲取前面兩者的結合······

下面我們來講下 Standalone project 插件腳本編寫方法,主要有以下幾大步驟:

  1. 在Android Studio中新建一個project,然后建立一個 Android Module,然后刪除掉目錄下除了 src/mainbuild.gradle 之外的其他內容,把 build.gradle 內容清空。
  2. src/main/ 目錄下創建一個 groovy 目錄,用于存放 Gradle 插件代碼。
  3. build.gradle 中添加 gradle sdkgroovy 語言支持
apply plugin: 'groovy'

dependencies {
    //gradle sdk
    compile gradleApi()
    //groovy sdk
    compile localGroovy()
}
  1. 現在,我們就可以進行 Gradle 插件代碼的具體編寫了,編寫方法跟java 基本一致,這里,我就給出一個簡單的 Demo:
package com.yn.test

import org.gradle.api.Plugin
import org.gradle.api.Project

class StandAlonePlugin implements Plugin<Project> {
    void apply(Project project) {
        note()
        //create an extension object:Whyn,so others can config via Whyn
        project.extensions.create("whyn", YNExtension)
        project.task('whyn'){
            group = "test"
            description = "gradle Standalone project demo,shares everywhere"
            doLast{
                println '**************************************'
                println "$project.whyn.description"
                println '**************************************'
            }

        }
    }

    private void note(){
        println '------------------------'
        println 'apply StandAlonePlugin'
        println '------------------------'
    }
}

class YNExtension {
    String description = 'default description'
}

這里,我們提供了擴展屬性的功能,方便我們在其他地方使用擴展屬性,讓我們的插件能夠接收傳遞信息。

  1. 代碼寫完后,為了讓 Gradle 能夠找到我們插件的實現類,我們還需要提供一個properties文件,具體做法如下:
    main 目錄下新建 resources 目錄,然后在 resources 目錄里面再新建 META-INF 目錄,再在 META-INF 里面新建 gradle-plugins目錄,最后在 gradle-plugins 里面新建一個 properties 文件(注:該 properties 的命名就是最后別人 apply plugin:時使用的名稱),最后在該 properties 文件內寫入插件完整包名:implementation-class=com.yn.test.StandAlonePlugin
    最后的目錄結構如下圖所示:
StandAlone project
  1. 最后,Standalone project 創建的插件需要先進行發布:Publish,才能被其他工程所使用。
    發布方法如下:
  • build.gradle 中添加如下內容:
apply plugin: 'maven-publish'

publishing {
    publications {
        mavenJava(MavenPublication) {

            groupId 'com.whyn.plugin'
            artifactId 'ynplugin'
            version '1.0.0'

            from components.java

        }
    }
}

publishing {
    repositories {
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url uri('D:/Android/repos')
        }
    }
}

從代碼中可以看到,我這里是把插件發布到我本地路徑: D:/Android/repos 中,如果把這個路徑換成網絡地址,那就是發布到網絡上。

  • 現在就可以打開控制臺窗口,輸入 gradlew publish 進行插件發布。
    發布成功后,你就可以在本地路徑中看到如下結果:

publish local

更多插件發布內容,請查看官網:Maven Publishing

  1. 到此,我們自定義的插件已經完成了編寫和發布過程了,最后要做的就是,在其他功能模塊中使用我們這個插件,具體方法如下:
  • 在工程的根目錄的 build.gradle 中添加如下內容:
buildscript {
    
    repositories {
        google()
        jcenter()
        maven {//local maven repo path
            url uri('D:/Android/repos')
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.0.0-alpha8'
        //group:artifactId:version
        classpath 'com.whyn.plugin:ynplugin:1.0.0'
//        classpath group: 'com.whyn.plugin', name: 'ynplugin', version: '1.0.0'            
    }
}
  • 然后,在Module的 build.gradleapply 這個插件:
//app build.gradle
apply plugin: 'com.whyn.plugin.StandAlone'

sync 一下,然后在控制臺輸入 gradlew whyn,你就可以看到以下輸出:

whyn_plugin_default_extension

可以看到,我們成功地輸出了插件中 description 的默認值,如果我們想改變這個值,那就再加載這個插件的 build.gradle 中配置一下我們插件提供的 extension

//app build.gradle
apply plugin: 'com.whyn.plugin.StandAlone'

whyn {
    description 'description in app build.gradle'
}

然后再 sync,再執行 gradlew whyn,就可以看到我們輸出了自定義配置的內容了:

whyn_plugin_custom_extension

順便在說一下,插件中 apply() 執行的時序是在我們 apply plugin: 的時候就會被調用執行的,也就是說,我們的 build.gradle 中錄入 apply plugin:'com.whyn.plugin.StandAlone'后,sycn 的時候,apply plugin:'com.whyn.plugin.StandAlone' 就會被執行,從而插件的 apply(Project project) 就會被調用執行,所以我們每次在 sync 的時候,都可以在 Gradle Console 窗口中看到 apply(Project project) 中的輸出信息:

sync

更多的自定義插件編寫詳情,請查看官網:Writing Custom Plugins

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容