背景
入職新公司后,發(fā)現(xiàn)項目中有用到python腳本根據(jù)自定義配置文件生成Java代碼的部分,而且腳本與配置文件以及生成的java代碼最終都上傳到代碼倉庫,因為沒有在編譯時生成代碼?。。?/strong>可能寫這部分的人員并沒有去接觸gradle插件的方法吧,筆者之見也沒有接觸過gradle插件開發(fā),不過在使用一些第三方庫比如room,dagger時對編譯時自動生成代碼有認知。
如用閑余時間研習了一下如何自定義gradle插件,接下來就進入正題
自定義插件方式
自定義gradle有以下幾種方式:
1.Build script
這種方式是直接在module的build.gradle中自定義,只在當前模塊使用。實際上的效果跟在gradle中自定義一個task區(qū)別不大
2. buildSrc project
這種插件腳本要求源碼放置在 rootProjectDir/buildSrc/src/main/groovy目錄內(nèi)(工程根目錄下創(chuàng)建 buildSrc 目錄),Gralde 會自動編譯和測試這個插件。這種方式創(chuàng)建的插件可在項目的所有模塊中使用
3.獨立的project
這種方式創(chuàng)建的插件可以發(fā)布到maven庫,可供第三方使用
本文只針對第三種方法簡單介紹
自定義獨立project的gradle插件
大致按照分為以下幾個步驟
1.新建一個android module,刪除除了res/main目錄和build.gradle之外的文件,刪除build.gradle中的內(nèi)容
2.新建res/main/groovy和res/main/resources文件夾。后面會在groovy文件夾中編寫gradle插件代碼,resources文件夾中再創(chuàng)建META-IFN文件夾,再在該文件夾中創(chuàng)建gradle-plugins文件夾,創(chuàng)建好之后應該是這樣的結構:

3.在groovy中創(chuàng)建包名目錄后,然后創(chuàng)建插件入口類
package com.sven.demo.gradle
import org.gradle.api.Plugin
import org.gradle.api.Project
class SvenGradlePlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.logger.quiet "* Sven gradle plugin loaded."
}
}
這個插件什么都沒做,只是打印了一行l(wèi)og
4.修改build.gradle腳本內(nèi)容如下:
apply plugin: 'groovy'
apply plugin: 'maven'
repositories {
mavenLocal()
jcenter()
}
dependencies {
compile gradleApi()
}
///////////////////////////////
// 發(fā)布到本地的maven倉庫
///////////////////////////////
// 插件版本號
def versionName = "1.0.0"
// 插件groupId
group "com.sven.plugin"
version versionName
uploadArchives{ //當前項目可以發(fā)布到本地文件夾中
repositories {
mavenDeployer {
// 定義本地maven倉庫的地址
// 這里指定為項目根目錄的repo文件夾
repository(url: uri('../repo'))
}
}
}
該文件內(nèi)容說明看注釋
5.在META-INF.gradle-plugins文件夾中新建custom-gradle.properties文件,文件內(nèi)容為:
implementation-class=com.sven.demo.gradle.SvenGradlePlugin
其中custom-gradle為插件使用時apply的名稱,即:
apply plugin: "custom-gradle"
implementation-class指定對應插件實現(xiàn),這里即為SvenGradlePlugin
-
發(fā)布到本地倉庫,上面的步驟都沒問題的情況下執(zhí)行插件項目的task: uploadArchives就可以發(fā)布到項目根目錄的repo文件夾中
uploadArchives.png
repo.png 成功上傳到本地maven庫后,就可以像使用第三方插件一樣使用我們的自定義插件了
根目錄的build.gradle中:
buildscript {
repositories {
google()
jcenter()
maven {
url uri('./repo')
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.sven.plugin:plugin:1.0.0'
}
}
app目錄的build.gradle中:
apply plugin: 'com.android.application'
apply plugin: 'custom-gradle'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.sven.demo.gradleplugin"
minSdkVersion 21
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
-
配置完后,sync或者編譯時會看到如下輸出:
gradle-log.png
我們打印的日志會在gradle插件加載時輸出
結語
至此我們自定義插件的第一步已經(jīng)完成,后續(xù)會繼續(xù)研究gradle插件自定義屬性以及如何使用JavaPoet生成代碼


