最近在研究編譯插樁的三種方法:AspectJ
、ASM
以及Redex
中的ASM
,要使用ASM就須要用插件的形式用在項目中,因此這篇的目的是瞭解並能本身定義一個Gradle插件。html
網上如今很不少這樣的文章,你們能夠結合起來看。java
Gradle
插件打包了可重用的構建邏輯,能夠在許多不一樣的項目和構建中使用。api
你能夠用你喜歡的編碼語言來實現一個自定義的Gradle插件,最終都會編譯城jvm字節碼。如今能夠實現插件的語言有Groovy
、java
、kotlin
等。通常來講,使用java或者kotlin實現的插件將優於使用groovy的相同插件。bash
實現插件的方式有三種,下面我會一一爲你們來介紹。閉包
你能夠直接在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中找到customPlugin
jvm
./gradlew -p app customPlugin --stacktrace
複製代碼
看下執行結果是什麼:maven
> Task :app:customPlugin
Hi this is a cutstom plugin
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
複製代碼
將插件源代碼放在rootProjectDir/buildScr/scr/main/groovy
中,這種的優勢在於自動編譯項目目錄下的buildSrc插件源碼,不須要手動指定 classpath。同一項目其餘模塊也可以使用。缺點就是對於其餘項目不可用。第三種方式就解決了這個缺點。ide
這裏若是想要了解能夠看這裏gradle
第三種和這個很相似,區別在於這是一個獨立的插件項目,能夠供其餘項目使用。
這種方式是如今目前大多數在使用的方式。
在 Android Studio
中新建Java Library
module customPlugin
,用IJ來開發插件會比AS要方便的不少。
用AS中開發插件須要這三步:
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很好實現嘛,這裏只是一個初步的介紹,更高級的用法能夠查看官方的文檔。
感謝大家看到這裏。