Gradle之自定義插件的三種形式(六)

自定義Gradle插件主要有三種形式,分別是build.gradle中編寫、buildSrc工程項目中編寫、獨立項目或獨立module中編寫。

1. 在build.gradle中編寫自定義插件

對象插件是實現了org.gradle.api.plugins接口的插件,這個接口中只定義個一個簡單的apply方法,想要實現自定義插件就需要去實現org.gradle.api.plugins接口。
Groovy、Java、Kotlin都可以作爲實現插件的語言,在本文的示例中,使用Groovy作爲實現語言。
在實際工作中我們很少會在build.gradle中編寫自定義插件,這裏是爲了帶大家寫個最簡單的例子,可以最快最直接的瞭解什麼是自定義插件。

1.1 這裏使用AS來編輯,新建一個項目,在module中的build.gradle中鍵入以下內容:

// Apply the plugin
apply plugin: GreetingPlugin

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        project.task('GreetingPluginTask') {
            doLast {
                println '自定義插件'
            }
        }
    }
}

在build.gradle中自定義了一個插件GreetingPlugin,在apply方法中創建一個名稱爲GreetingPluginTask的任務。在AS的Terminal中輸入gradlew.bat GreetingPluginTask來執行GreetingPluginTask任務。

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradle>gradle  GreetingPluginTask

> Task :app:GreetingPluginTask 
自定義插件


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

1.2 自定義插件擴展

再舉一個簡單的插件拓展例子,通過插件拓展來配置GreetingPluginTask的輸出字符串,如下所示。
build.gradle

apply plugin: GreetingPlugin
greeting.message="自定義插件拓展"//2
class GreetingPluginPluginExtension{
    String message="from GreetingPlugin"
}
class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        def extension=project.extensions.create("greeting",GreetingPluginPluginExtension)//1
        project.task('GreetingPluginTask') {
            doLast {
                println extension.message
            }
        }
    }
}

GreetingPluginPluginExtension類中定義了message變量,GreetingPluginPluginExtension是一個Groovy Bean(類似於JavaBean)。註釋1處用於添加拓展插件GreetingPluginPluginExtension到插件列表中,名稱爲greeting。註釋2處設置GreetingPluginPluginExtension的message值。
Terminal中輸入gradlew.bat GreetingPluginTask來執行GreetingPluginTask任務。

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradle>gradle GreetingPluginTask

> Task :app:GreetingPluginTask 
自定義插件拓展


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

2. buildSrc工程項目

除了在build.gradle中編寫的自定義插件,還可以將插件的源代碼放在rootProjectDir/buildSrc/src/main/groovy目錄中,Gradle會自動識別來完成編譯和測試。Android Studio會找rootPrjectDir/buildSrc/src/main/groovy目錄下的代碼。

坑:當新建libraray module並命名爲buildSrc後會提示Plugin with id'com.android.library' not found.

這是因爲buildSrc是Android的保留名稱,只能作爲plugin插件使用,我們修改buildSrc的build.gradle文件後就不報錯了。

具體流程如下:

2.1. 首先創建一個名爲buildSrc的module,注意,名稱必須爲buildSrc

image

2.2. 然後將其它不需要的文件刪除,新建需要的文件夾和文件,最後的目錄結構如下圖所示:

image

2.3. 新建對應的文件和文件夾之後,工程開始會不認這個buildSrc,我們修改build.gradle:

apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

點擊Sync Now,完了之後發現groovy文件夾變藍色了

2.4. 在對應的包下面新建YolynPlugin.groovy,輸入以下內容

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

class YolynPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('yolynplugin') {
            doLast {
                println("this is YolynPlugin")
            }
        }
        println("welcome to YolynPlugin")
    }
}

2.5. 再在com.yolyn.plugin.properties文件中添加以下內容(注意這裏properties的名稱就是我們之後要引用這個插件時apply plugin:''引號填入的內容)

implementation-class=YolynPlugin

這裏的YolynPlugin就是我們創建的YolynPlugin.groovy文件,一定要對應上,否則會報找不到的錯誤。

2.6. 在app的gradle中去引用這個插件

apply plugin:  'com.yolyn.plugin'

com.yolyn.plugin是我們之前創建的properties的名稱

重新build一下

2.7. 在terminal中可以鍵入命令

gradle yolynplugin   
或者gradlew yolynplugin  
或者gradlew.bat yolynplugin

輸出內容:

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle yolynplugin

> Configure project :app 
welcome to YolynPlugin

> Task :app:yolynplugin 
this is YolynPlugin


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

疑問1
這裏有一個疑問,爲什麼先打印出welcome to YolynPlugin,是因爲doLast嗎,怎麼解釋?
疑問2
我們再創建一個插件叫OtherPlugin.groovy

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

class OtherPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task('otherplugin') {
            doLast {
                println("this is OtherPlugin")
            }
        }
        println("Welcome To OtherPlugin")
    }
}   

然後同樣地在gradle-plugins中創建properties,在app下面的build.gradle引用

在Terminal中輸入gradle otherplugin

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle otherplugin

> Configure project :app 
welcome to YolynPlugin
Welcome To OtherPlugin

> Task :app:otherplugin 
this is OtherPlugin


BUILD SUCCESSFUL in 2s
1 actionable task: 1 executed

發現YolynPlugin中的apply方法也執行了

疑問3
我們把兩個Plugin中的doLast去掉
我們再在Terminal中輸入gradle otherplugin

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle otherplugin

> Configure project :app 
this is YolynPlugin
welcome to YolynPlugin
this is OtherPlugin
Welcome To OtherPlugin


BUILD SUCCESSFUL in 6s

發現全部都打印出來了,這是爲什麼?

  1. 對於疑問1:
    我們看一下官方對Projec的task方法的介紹
Creates a Task with the given name and adds it to this project. Calling this method is equivalent to calling task(java.util.Map, String) with an empty options map.

After the task is added to the project, it is made available as a property of the project, so that you can reference the task by name in your build file. See here for more details

If a task with the given name already exists in this project, an exception is thrown.

throws:
    InvalidUserDataException If a task with the given name already exists in this project.

Parameters:
    name - The name of the task to be created

Returns:
    The newly created task object

大致意思是會創建一個給定名字的task放到這個project裏面,調用這個方法相當於調用這個task

再看一下Task的doLast方法:

Adds the given closure to the end of this task's action list. The closure is passed this task as a parameter when executed.

這樣就能解釋了,確實是因爲doLast將任務添加到project的tasks的list的最後了,所以才最後執行。具體還可以查看官方文檔的Project,文檔在gradle安裝目錄的docs裏面可以找到。

==疑問二和疑問三是爲什麼???求解==

日後繼續研究
再看第三種形式

3. 獨立項目或獨立Module

無論是在build.gradle中編寫自定義插件,還是buildSrc項目中編寫自定義插件,都只能在自己的項目中進行使用。如果想要分享給其他人或者自己用,可以在一個獨立的項目中編寫插件,這個項目會生成一個包含插件類的JAR文件,有了JAR文件就很容易進行分享了。

3.1 創建一個名爲YolynPlugin的module

跟上面創建buildSrc一樣,將其它文件刪除,並創建相應的文件和文件夾,最終目錄結構如下:

image

3.2 修改build.gradle

apply plugin:'groovy'
apply plugin: 'maven'
dependencies {
    //gradle sdk
    compile gradleApi()
    //groovy sdk
    compile localGroovy()
}

Sync Now

3.3 在com.example.yolynplugin下創建ModuleYolynPlugin.groovy(爲了和上面的YolynPlugin區分)

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

class ModuleYolynPlugin implements Plugin<Project> {

    @Override
    void apply(Project project) {
        project.task("moduleyolynplugin") {
            println("this is module yolynplugin")
        }
    }
}

3.4 在gradle-plugins文件夾下面創建com.example.yolynplugin.properties

implementation-class=ModuleYolynPlugin

3.5 將代碼上傳到倉庫或者本地,這裏是放到本地

在這個module的build.gradle追加下面內容

group='com.example.yolynplugin'
version='1.0.0'
//group和version在後面會用到
uploadArchives {
    repositories {
        mavenDeployer {
              //提交到遠程服務器:
              // repository(url: "http://www.xxx.com/repos") {
              //    authentication(userName: "admin", password: "admin")
              // }
            repository(url:uri('../repo'))
        }
    }
}

上面各個參數的邏輯意義參考官方文檔:
https://docs.gradle.org/current/dsl/index.html
這裏直接將插件上傳到了本項目的根目錄,點擊Build之後在Gradle窗口會看到uploadArchives

image

點擊uploadArchives會在本地生成插件相關的文件,比如我的目錄和文件如下圖所示

image

圖中的YolynPlugin-1.0.0.jar就是我們需要的插件jar包。

3.6 去app下面的module中引用

在build.gradle中追加下面內容

apply plugin: 'com.example.yolynplugin'//properties的名字
buildscript {
//repositories這個模塊的內容告訴gradle去什麼地址下載第三方的庫。
    repositories{
        maven {
        url uri('../repo')
        }
    }
    dependencies{
                   //group:pluginName:version
        classpath 'com.example.yolynplugin:YolynPlugin:1.0.0'
    }
}

其中com.example.yolynplugin是group,YolynPlugin是自定義插件的名稱,1.0.0是版本號

也可以這麼寫:

dependencies {
     classpath group: 'com.example.yolynplugin', name: 'YolynPlugin',
             version: '1.0.0'
 }

Sync Now

3.7 clean一下Project,然後make Project,在Terminal中輸入:gradle moduleyolynplugin

D:\DevelopSoftWare_Location\Android_Studio\DemoWorkSpace\DefinedGradleDemo1>gradle moduleyolynplugin

> Configure project :app 
welcome to YolynPlugin
Welcome To OtherPlugin
this is module yolynplugin


BUILD SUCCESSFUL in 8s

三個插件都成功運行

筆記來源於:
1.https://blog.csdn.net/huachao1001/article/details/51810328
2. http://liuwangshu.cn/application/gradle/6-custonplugin.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章