Android gradle 自定義插件


Gradle 的插件有三種打包方式:

  • 構建腳本:插件邏輯寫在 build.gradle 中,適用於邏輯簡單的任務,但是該方式實現的插件在該構建腳本之外是不可見的,只能用於當前腳本。
  • buildSrc項目:根據語言插件代碼放在 rootProjectDir/buildSrc/src/main/groovy 目錄中或者 rootProjectDir/buildSrc/src/main/java 或者rootProjectDir/buildSrc/src/main/kotlin,該插件對於該項目中構建使用的每個構建腳本都是可見的,適用於邏輯復雜但又不需要對外可見的插件

  • 獨立項目:一個獨立的 Groovy/Java/Kotlin 項目,該項目生成並發布一個 jar 然后可以在多個版本中使用它並與他人共享,並且此 jar 包可能包含一些插件,或者將多個相關的任務類捆綁到單個庫中

接下來我們先從基本的構建腳本中的插件開始 

1、構建腳本:

創建 Gradle 插件,需要創建一個實現 Plugin 接口的類,當插件應用於項目時,Gradle 會創建插件類的實例並調用實例的 apply() 方法,如果需要的話,插件還可以用於配置項目

把插件變得可配置,添加一些簡單擴展屬性到 project 上,比如可以添加一個 greeting 擴展對象到 project 上,這就允許我們去配置 greeting 對象。

文件是 build.gradle:

class GreetingPluginExtension {
    String message = 'Hello from GreetingPlugin'
}

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Add the 'greeting' extension object
        def extension = project.extensions.create('greeting', GreetingPluginExtension)
        // Add a task that uses configuration from the extension object
        project.task('hello') {
            doLast {
                println extension.message
            }
        }
    }
}

apply plugin: GreetingPlugin

// Configure the extension
greeting.message = 'Hi from Gradle'

2、獨立項目 

創建Gradle Module

AndroidStudio中是沒有新建類似Gradle Plugin這樣的選項的,那我們如何在AndroidStudio中編寫Gradle插件,並打包出來呢?

  1. 首先,你得新建一個Android Project

  2. 然后再新建一個 Module,這個 Module用於開發 Gradle 插件,同樣,Module 里面沒有 gradle plugin 給你選,但是我們只是需要一個“容器”來容納我們寫的插件,因此,你可以隨便選擇一個 Module 類型(如 Phone & Tablet Module 或 Android Librarty ),因為接下來一步我們是將里面的大部分內容刪除,所以選擇哪個類型的 Module 不重要。

  3. 將 Module 里面的內容刪除,只保留 build.gradle 文件和 src/main 目錄。

  4. 由於 gradle 是基於 groovy,因此,我們開發的 gradle 插件相當於一個 groovy 項目。所以需要在 main 目錄下新建 groovy 目錄

  5. groovy 又是基於Java,因此,接下來創建groovy的過程跟創建java很類似。在 groovy 新建包名,如:com.sjq.greetplugin,然后在該包下新建groovy文件,通過  new->file→GreetingPlugin.groovy 來新建名為 GreetingPlugin 的 groovy 文件。一定是要有.groovy 后綴文件。

  6. 為了讓我們的 groovy 類申明為 gradle 的插件,新建的 groovy 需要實現 org.gradle.api.Plugin 接口。

如下所示:

package com.sjq.greetplugin  // 包名一定要有,不然打包不會打進對應包里去,很可能就會出現類找不到的情況。

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

class GreetingPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task("publishPluginTest"){ // task 名字
            doLast {
                println("新內容是:null")
            }
        }
    }
}

定義好了自己的 gradle 插件類,接下來就是告訴 gradle,哪一個是我們自定義的插件類,因此,需要在 main 目錄下新建 resources 目錄,然后在resources 目錄里面再新建 META-INF 目錄,再在 META-INF 里面新建 gradle-plugins 目錄。最后在 gradle-plugins 目錄里面新建 properties 文件,注意這個文件的命名,你可以隨意取名,但是后面使用這個插件的時候,會用到這個名字。比如,你取名為 com.sjq.gradle.properties,而在其他build.gradle 文件中使用自定義的插件時候則需寫成: 

apply plugin: 'com.sjq.greetplugin'

然后在com.hc.gradle.properties文件里面指明你自定義的類

implementation-class=com.sjq.greetplugin.GreetingPlugin // 注意后面跟的是插件名字,注意大小寫

此處我們還是采用包名,方便記憶。

到這里后,整個目錄結果如下圖所示:

因為我們要用到 groovy 以及后面打包要用到 maven, 所以在我們自定義的 Module 下的 build.gradle 需要添加如下代碼:

apply plugin: 'groovy'
apply plugin: 'maven'

dependencies {
//gradle sdk
compile gradleApi()
//groovy sdk
compile localGroovy()
}

repositories {
mavenCentral()
}

打包到本地Maven

前面我們已經自定義好了插件,接下來就是要打包到 Maven 庫里面去了,你可以選擇打包到本地,或者是遠程服務器中。在我們自定義 Module 目錄下的 build.gradle 添加如下代碼:

//group和version在后面使用自定義插件的時候會用到
group='com.hc.plugin'
version='1.0.0'

uploadArchives {
    repositories {
        mavenDeployer {
            //提交到遠程服務器:
           // repository(url: "http://www.xxx.com/repos") {
            //    authentication(userName: "admin", password: "admin")
           // }
            //本地的Maven地址設置為../repos
            repository(url: uri('../repos'))
        }
    }
}

其中,group 和 version 后面會用到,我們后面再講。雖然我們已經定義好了打包地址以及打包相關配置,但是還需要我們讓這個打包 task 執行。點擊 AndroidStudio 右側的 gradle 工具,如下圖所示:

可以看到有 uploadArchives 這個 Task,雙擊 uploadArchives 就會執行打包上傳啦!執行完成后,去我們的 Maven 本地倉庫查看一下:

其中,com/sjq/greetplugin 這幾層目錄是由我們的 group 指定,myplugin 是模塊的名稱,1.0.0 是版本號( version 指定)。 

使用自定義的插件

接下來就是使用自定義的插件了,一般就是在 app 這個模塊中使用自定義插件,因此在 app 這個 Module 的 build.gradle 文件中,需要指定本地 Maven 地址、自定義插件的名稱以及依賴包名。簡而言之,就是在 app 這個 Module 的 build.gradle 文件中后面附加如下代碼:

buildscript {
    repositories {
        maven {//本地Maven倉庫地址
            url uri('../repos')
        }
    }
    dependencies {
        //格式為-->group:module:version
        classpath 'com.sjq.greetplugin:GreetingPlugin:1.0.0'
    }
}
//com.sjq.greetplugin 為 resources/META-INF/gradle-plugins 下的 properties 文件名稱
apply plugin: 'com.sjq.greetplugin'

在當前目錄下輸入命令行:

./gradlew -q publishPluginTest 

運行結果:

3、開發只針對當前項目的Gradle插件

前面我們講了如何自定義 gradle 插件並且打包出去,可能步驟比較多。有時候,你可能並不需要打包出去,只是在這一個項目中使用而已,那么你無需打包這個過程。

只是針對當前項目開發的 Gradle 插件相對較簡單。步驟之前所提到的很類似,只是有幾點需要注意:

新建的 Module 名稱必須為 BuildSrc,無需 resources 目錄

其中,build.gradle 內容為:

// 依賴groovy插件
plugins {
    id 'groovy'
}

dependencies {
    implementation gradleApi()
    implementation localGroovy()
}

CustomPluginB 內容是

package com.sjq.happy.myplugin

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

// 在單獨的groovy文件中定義插件類
class CustomPluginB implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('CustomPluginTaskB') {
            doFirst {
                println 'This is custom plugin TaskB'
            }
        }
    }
}

app這個Module中如何使用呢?直接在app的build.gradle下加入

import com.sjq.happy.myplugin.CustomPluginB 

在輸入命令行:

 ./gradlew -q CustomPluginTaskB

結果如下圖所示:

需要注意的是:

如果使用的 gradle 版本大於等於 6.0 ,那么在你使用的時候會提示以下錯誤

enter image description here

'buildSrc' cannot be used as a project name as it is a reserved name.

但是如果你是在 6.0 以下遇到這個問題,可以嘗試使用以下方法解決:

  1. 打開你的 settings.gradle / settings.gradle.kts 文件

  2. 將 "buildSrc" 從 included modules 移除

  3. 重新編譯

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM