前言
我們平常在進(jìn)行Android開(kāi)發(fā)時(shí)熊响,都會(huì)使用 Gradle 來(lái)進(jìn)行項(xiàng)目配置奖唯,通常在對(duì)應(yīng)的module:app的build.gradle
中,在最上面的一句話一般都為:
apply plugin: 'com.android.application'
這句話就是用來(lái)加載gradle的android
開(kāi)發(fā)插件庞瘸,然后焰薄,我們就可以使用該插件提供的配置方法進(jìn)行Android項(xiàng)目的配置了,即如下所示:
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
插件配置詳情跟压,請(qǐng)查看:Android Plugin DSL Reference
簡(jiǎn)單來(lái)講胰蝠,Gradle插件允許我們做一些額外的擴(kuò)展工作,比如我想在module每次build完成后震蒋,把生成的jar/aar移動(dòng)到另一個(gè)項(xiàng)目的libs文件內(nèi)茸塞,相當(dāng)于動(dòng)態(tài)更新庫(kù)文件······
其實(shí)像上面這種操作用 Gradle 的 task
就可以完成,但是使用 task
的一個(gè)弊端就是沒(méi)辦法做到復(fù)用查剖,而使用 Gradle 你就能在任何項(xiàng)目钾虐,任何模塊中使用同一套邏輯功能,甚至于你還能對(duì)不同的模塊進(jìn)行動(dòng)態(tài)化的個(gè)性配置笋庄,只要插件代碼支持即可禾唁。
更多 Gradle 使用方法,請(qǐng)查看官網(wǎng):Gradle User Guide
自定義插件
上面我們說(shuō)了自定義插件的諸多好處无切,那么荡短,究竟該如何進(jìn)行 Gradle 自定義插件的編寫呢 ?
其實(shí),自定義插件基于源碼放置可以分為3種:
- 第一種:Build script
這種插件腳本的源碼放置在模塊內(nèi)的build.gradle
中哆键,好處就是插件腳本會(huì)被自動(dòng)編譯并添加進(jìn)模塊的classpath
中掘托,我們完全不用做任何事情。但是籍嘹,這種插件腳本只能在聲明的這個(gè)build.gradle
中使用闪盔,其他模塊是沒(méi)辦法復(fù)用這個(gè)插件的弯院。
//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"
}
}
}
}
如上面這個(gè)插件 GreetingPlugin
,我們是在 app
的 build.gradle
中聲明定義的,然后泪掀,在控制臺(tái)運(yùn)行下: gradle app:tasks
听绳,或者直接看Android Studio的Gradle窗口,可以看到如下結(jié)果:
可以看到异赫,只有我們聲明編寫的 app
中成功添加了一個(gè) task:hello
(根目錄也會(huì)同時(shí)添加進(jìn)這個(gè)插件功能)椅挣,然后,你在工程其他 build.gradle
中 apply plugin: GreetingPlugin
是無(wú)法成功的塔拳,因?yàn)檫@種插件對(duì)其他模塊是不可見(jiàn)的鼠证。
所以,Build script 這種插件其實(shí)跟直接定義一個(gè) task
沒(méi)有多大區(qū)別靠抑。
- 第二種:buildSrc project
這種插件腳本要求源碼放置在rootProjectDir/buildSrc/src/main/groovy
目錄內(nèi)(也就是工程根目錄下創(chuàng)建 buildSrc 目錄)量九,然后 Gradle 就會(huì)自動(dòng)編譯和測(cè)試這個(gè)插件,同時(shí)颂碧,這種方法創(chuàng)建的插件對(duì)工程內(nèi)的所有模塊都是可以使用的荠列。
從上圖可以看到,我們?cè)谀K
app
中成功加載了插件载城,所以肌似,使用 buildSrc project 這種插件腳本方法就使得我們創(chuàng)建了一個(gè)工程插件。
在你工程只需擴(kuò)展本工程額外功能个曙,不需與其他工程或者其他開(kāi)發(fā)者進(jìn)行共用時(shí)锈嫩,buildSrc project 這種插件開(kāi)發(fā)或許是個(gè)不錯(cuò)的選擇。
- 第三種:Standalone project
這種方法就是使用單獨(dú)的一個(gè)工程/模塊創(chuàng)建我們的 Gradle 插件垦搬,這種方法會(huì)構(gòu)建和發(fā)表一個(gè)JAR文件呼寸,可以提供給多工程構(gòu)建和其他開(kāi)發(fā)者共同使用。通常來(lái)說(shuō)猴贰,JAR文件內(nèi)可能包含有一些自定義的插件腳本对雪,或者是由一些相關(guān)的task
類組合成的一個(gè)庫(kù),獲取前面兩者的結(jié)合······
下面我們來(lái)講下 Standalone project 插件腳本編寫方法米绕,主要有以下幾大步驟:
- 在Android Studio中新建一個(gè)project瑟捣,然后建立一個(gè) Android Module,然后刪除掉目錄下除了
src/main
和build.gradle
之外的其他內(nèi)容栅干,把build.gradle
內(nèi)容清空迈套。 - 在
src/main/
目錄下創(chuàng)建一個(gè)groovy
目錄,用于存放 Gradle 插件代碼碱鳞。 - 在
build.gradle
中添加gradle sdk
和groovy
語(yǔ)言支持
apply plugin: 'groovy'
dependencies {
//gradle sdk
compile gradleApi()
//groovy sdk
compile localGroovy()
}
- 現(xiàn)在桑李,我們就可以進(jìn)行 Gradle 插件代碼的具體編寫了,編寫方法跟java 基本一致,這里贵白,我就給出一個(gè)簡(jiǎn)單的
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'
}
這里率拒,我們提供了擴(kuò)展屬性的功能,方便我們?cè)谄渌胤绞褂脭U(kuò)展屬性禁荒,讓我們的插件能夠接收傳遞信息猬膨。
- 代碼寫完后,為了讓 Gradle 能夠找到我們插件的實(shí)現(xiàn)類呛伴,我們還需要提供一個(gè)properties文件勃痴,具體做法如下:
在main
目錄下新建resources
目錄,然后在resources
目錄里面再新建META-INF
目錄磷蜀,再在META-INF
里面新建gradle-plugins
目錄召耘,最后在gradle-plugins
里面新建一個(gè) properties 文件(注:該 properties 的命名就是最后別人apply plugin:
時(shí)使用的名稱)百炬,最后在該 properties 文件內(nèi)寫入插件完整包名:implementation-class=com.yn.test.StandAlonePlugin
褐隆。
最后的目錄結(jié)構(gòu)如下圖所示:
- 最后,Standalone project 創(chuàng)建的插件需要先進(jìn)行發(fā)布:
Publish
剖踊,才能被其他工程所使用庶弃。
發(fā)布方法如下:
- 在
build.gradle
中添加如下內(nèi)容:
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')
}
}
}
從代碼中可以看到,我這里是把插件發(fā)布到我本地路徑: D:/Android/repos
中德澈,如果把這個(gè)路徑換成網(wǎng)絡(luò)地址歇攻,那就是發(fā)布到網(wǎng)絡(luò)上。
- 現(xiàn)在就可以打開(kāi)控制臺(tái)窗口梆造,輸入
gradlew publish
進(jìn)行插件發(fā)布缴守。
發(fā)布成功后,你就可以在本地路徑中看到如下結(jié)果:
更多插件發(fā)布內(nèi)容镇辉,請(qǐng)查看官網(wǎng):Maven Publishing
- 到此屡穗,我們自定義的插件已經(jīng)完成了編寫和發(fā)布過(guò)程了,最后要做的就是忽肛,在其他功能模塊中使用我們這個(gè)插件村砂,具體方法如下:
- 在工程的根目錄的
build.gradle
中添加如下內(nèi)容:
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.gradle
中apply
這個(gè)插件:
//app build.gradle
apply plugin: 'com.whyn.plugin.StandAlone'
sync
一下屹逛,然后在控制臺(tái)輸入 gradlew whyn
础废,你就可以看到以下輸出:
可以看到,我們成功地輸出了插件中
description
的默認(rèn)值罕模,如果我們想改變這個(gè)值评腺,那就再加載這個(gè)插件的 build.gradle
中配置一下我們插件提供的 extension
:
//app build.gradle
apply plugin: 'com.whyn.plugin.StandAlone'
whyn {
description 'description in app build.gradle'
}
然后再 sync
,再執(zhí)行 gradlew whyn
淑掌,就可以看到我們輸出了自定義配置的內(nèi)容了:
順便在說(shuō)一下蒿讥,插件中 apply()
執(zhí)行的時(shí)序是在我們 apply plugin:
的時(shí)候就會(huì)被調(diào)用執(zhí)行的,也就是說(shuō),我們的 build.gradle
中錄入 apply plugin:'com.whyn.plugin.StandAlone'
后诈悍,sycn
的時(shí)候祸轮,apply plugin:'com.whyn.plugin.StandAlone'
就會(huì)被執(zhí)行,從而插件的 apply(Project project)
就會(huì)被調(diào)用執(zhí)行侥钳,所以我們每次在 sync
的時(shí)候适袜,都可以在 Gradle Console
窗口中看到 apply(Project project)
中的輸出信息:
更多的自定義插件編寫詳情,請(qǐng)查看官網(wǎng):Writing Custom Plugins