帶你實現自定義Gradle插件

前言

最近在研究編譯插樁的三種方法:AspectJASM以及Redex中的ASM,要使用ASM就須要用插件的形式用在項目中,因此這篇的目的是瞭解並能本身定義一個Gradle插件。html

網上如今很不少這樣的文章,你們能夠結合起來看。java

Gradle插件打包了可重用的構建邏輯,能夠在許多不一樣的項目和構建中使用。api

你能夠用你喜歡的編碼語言來實現一個自定義的Gradle插件,最終都會編譯城jvm字節碼。如今能夠實現插件的語言有Groovyjavakotlin等。通常來講,使用java或者kotlin實現的插件將優於使用groovy的相同插件。bash

實現插件的方式有三種,下面我會一一爲你們來介紹。閉包

實現方式

Build Script

你能夠直接在build.gradle中構建一些簡單的插件代碼,這樣作能夠自動編譯幷包含在構建腳本的類路徑中,無需執行任何操做。可是該插件只能用於本項目中,外部不可見。app

class GreetingExtension {
    String message = null

}

class GreetingPlugin implements Plugin<Project> {

    @Override
    void apply(Project target) {
        // 利用利用Extension建立greeting 閉包,用於接受外部傳遞的參數值
        def extension = target.extensions.create("greeting", GreetingExtension)

        target.task("customPlugin") {
            doLast() {
                println(extension.message)
            }
        }
    }
}

/**
 * 使用 greeting{}要放在 apply plugin 以後,apply plugin會執行apply方法進行綁定操做
 * */
apply plugin: GreetingPlugin

greeting {
    message = "Hi this is a cutstom plugin"
}
複製代碼

咱們能夠用命令行 或者AS右邊的gradle在app中找到customPluginjvm

./gradlew -p app customPlugin --stacktrace
複製代碼

看下執行結果是什麼:maven

> Task :app:customPlugin
Hi this is a cutstom plugin

BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed

複製代碼

buildSrc project

將插件源代碼放在rootProjectDir/buildScr/scr/main/groovy中,這種的優勢在於自動編譯項目目錄下的buildSrc插件源碼,不須要手動指定 classpath。同一項目其餘模塊也可以使用。缺點就是對於其餘項目不可用。第三種方式就解決了這個缺點。ide

這裏若是想要了解能夠看這裏gradle

第三種和這個很相似,區別在於這是一個獨立的插件項目,能夠供其餘項目使用。

Standalone project

這種方式是如今目前大多數在使用的方式。

Android Studio中新建Java Library module customPlugin,用IJ來開發插件會比AS要方便的不少。

用AS中開發插件須要這三步:

  1. 移除java文件。
  2. 增長groovy文件夾,這裏放全部插件的代碼。
  3. 增長resources文件夾,這用來聲明插件指向地址。
  4. 修改build.gradle文件
apply plugin: 'groovy'
apply plugin: 'maven'

repositories {
    mavenCentral()
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation gradleApi() // gradler sdk
    implementation localGroovy() // groovy sdk
}

uploadArchives {
    repositories {
        mavenDeployer {
            //設置插件的GAV參數
            pom.groupId = 'com.lenny.plugin'
            pom.artifactId = 'art'// 這個若是不設置,發佈以後應該是com.lenny.plugin.customPlugin
            pom.version = '1.0.3'
            //文件發佈到下面目錄
            repository(url: uri('../repo'))
        }
    }
}
複製代碼

修改後的目錄應該是這個樣子的:

 ├── build.gradle 
 ├── libs 
 ├── customPlugin.iml 
 └── src     
    └── main
        ├── groovy     
    │          └── com    
    │              └── lenny     
    │                  └── plugin     
    │                      ├── CustomPlugin.groovy     
    │                          
    └── resources         
        └── META-INF             
            └── gradle-plugins                 
            └── com.lenny.plugin.properties


複製代碼

CustomPlugin.groovy

package com.lenny.plugin

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

public class CustomPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        println("hello from custom plugin")
    }
}
複製代碼

注意文件的後綴。

com.lenny.plugin.properties

implementation-class=com.lenny.plugin.CustomPlugin
複製代碼

到這裏就算基本完成了,咱們同步下代碼,就能夠在右側的Gradle中找到uploadArchives命令,執行該命令以後就會在項目同級目錄下發現:

└── repo    
    └── com
        ├── lenny     
    │          └── plugin    
    │              └── art     
    │                  └── 1.0.3     
    │                      ├── art-1.0.3.jar
    │                      ├── art-1.0.3.jar.md5
    │                      ├── art-1.0.3.jar.sha1
    │                      ├── art-1.0.3.pom
    │                      ├── art-1.0.3.pom.md5
    │                      ├── art-1.0.3.pom.sha1
 
複製代碼

而後咱們在項目中集成:

工程的build.gradle

buildscript {
    repositories {
        ...
        maven {
            url uri('repo/')
        }
    }
    dependencies {
        ...
        classpath 'com.lenny.plugin:art:1.0.3'
    }
}
複製代碼

app的build.gradle

apply plugin: 'com.lenny.plugin'
複製代碼

若是是發佈在上線的,repositoies中就不這麼寫了。

classpath xxx的由來:groupId:artifactId:version

apply plugin: 'xxx'中則是properties的前面的:com.lenny.plugin

執行結果:

> Configure project :app
hello from custom plugin

> Task :app:createMockableJar UP-TO-DATE
> Task :app:preBuild UP-TO-DATE
複製代碼

總結

這樣一遍走下來,是否是以爲自定義gradle很好實現嘛,這裏只是一個初步的介紹,更高級的用法能夠查看官方的文檔。

感謝大家看到這裏。

參考資料

開發自定義Gradle插件

相關文章
相關標籤/搜索