前言
上一篇文章已經(jīng)給大家詳細(xì)介紹了如何通過Gradle將我們開發(fā)好的Library上傳到JCenter男旗,基本上就是一系列配置烤惊,最后通過Gradle腳本將Library打包成jar或者aar包上傳到maven倉庫遂庄,然后添加到JCenter倉庫進(jìn)行審核,通過之后就能讓開發(fā)者在gradle腳本進(jìn)行引用。本篇博客還是基于Gradle切距,但稍微進(jìn)階一下趾徽,將跟大家分享一下如何開發(fā)一個(gè)Gradle插件续滋,這個(gè)插件是我為Bugly開發(fā)的自動(dòng)上傳apk文件的Gradle插件,目前已經(jīng)開源孵奶,有興趣的朋友可以到github看看:https://github.com/BuglyDevTeam/BuglyBetaUploader疲酌。
什么是Gradle插件?
這個(gè)問題問得很好了袁,我們來舉個(gè)例子朗恳,在使用Android Studio進(jìn)行開發(fā)的時(shí)候,我們創(chuàng)建一個(gè)Android工程载绿,會(huì)默認(rèn)生成一個(gè)build.gradle腳本粥诫,打開腳本你會(huì)看到以下代碼:
apply plugin: 'com.android.application'
大家有沒有想過為什么會(huì)有這么一句代碼?如果我們創(chuàng)建一個(gè)Library的話卢鹦,就會(huì)變成:
apply plugin: 'com.android.library'
其實(shí)這就是在gradle腳本引用android為我們提供的插件臀脏,plugin表示插件,'com.android.application’表示我們引用的插件名冀自,通常是以包名來命名揉稚。
這里還有一個(gè)問題,這個(gè)插件是怎么被引用進(jìn)來的熬粗?我們可以在根目錄找到另外一個(gè)build.gradle文件搀玖,打開可以看到以下代碼:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
稍微解釋下,buildscript方法是定義了全局的相關(guān)屬性驻呐,repositories定義了jcenter作為倉庫灌诅。一個(gè)倉庫代表著你的依賴包的來源,例如maven倉庫含末。dependencies用來定義構(gòu)建過程猜拾。classpath 'com.android.tools.build:gradle:2.0.0'
,就是將遠(yuǎn)程的插件下載到本地并將其構(gòu)建到我們工程當(dāng)中佣盒。
那怎么找到插件下載的路徑呢挎袜,如下圖所示 :
你可以看到我們在android studio所用到的所有插件和Library都會(huì)下載這個(gè)目錄下,這下子你應(yīng)該對gradle引用插件的原理有一定的理解了吧。
如何開發(fā)Gradle插件盯仪?
這個(gè)也是本篇博客要講的內(nèi)容紊搪,要理解這部分內(nèi)容需要大家先去了解Groovy這個(gè)語言,因?yàn)槲覀冮_發(fā)Gradle插件使用的就是Groovy語言全景,可以看看在開源中國對這門語言的描述:
這部分內(nèi)容同學(xué)們自己去研究耀石,本篇博客不會(huì)過多的講解它的語法,其實(shí)你完全可以將它作為Java來用爸黄,后面你可以看到我寫的一些代碼其實(shí)跟Java沒有太大差別滞伟。
步驟1:創(chuàng)建groovy工程
在Android Studio不能直接創(chuàng)建groovy工程,但我們可以按照下面步驟來創(chuàng)建:
- 創(chuàng)建一個(gè)Android項(xiàng)目
- 新建一個(gè)module炕贵,選擇Androd Library
- 刪除除build.gradle之外的所有文件
- 按照Groovy工程模板創(chuàng)建對應(yīng)的目錄
最終創(chuàng)建出來的工程如下圖所示:
第4步:在新建的module中新建文件夾src诗良,接著在src文件目錄下新建main文件夾,在main目錄下新建groovy目錄鲁驶,這時(shí)候groovy文件夾會(huì)被Android識(shí)別為groovy源碼目錄鉴裹。除了在main目錄下新建groovy目錄外,你還要在main目錄下新建resources目錄钥弯,同理resources目錄會(huì)被自動(dòng)識(shí)別為資源文件夾径荔。在groovy目錄下新建項(xiàng)目包名,就像Java包名那樣脆霎。resources目錄下新建文件夾META-INF总处,META-INF文件夾下新建gradle-plugins文件夾
步驟2:配置gradle
apply plugin: 'groovy'
apply plugin: 'maven'
dependencies {
compile gradleApi()
compile localGroovy()
}
repositories {
mavenCentral()
}
group = 'com.tencent.bugly.plugin'
version = '1.0.0'
uploadArchives {
repositories {
mavenDeployer {
repository(url: uri('../repo'))
}
}
}
group將會(huì)表示插件的groupId,version表示插件的版本睛蛛,這段代碼會(huì)在gradle toolbar生成一個(gè)task鹦马,執(zhí)行這個(gè)task會(huì)將插件發(fā)布到本地的repo目錄下,這里注意下忆肾,我們正在開發(fā)階段荸频,不需要將gradle插件上傳到maven,我們將它發(fā)布到自己指定的目錄下即可客冈。
執(zhí)行uploadArchives這個(gè)task旭从,就會(huì)在repo目錄下生成指定版本的插件:
步驟3:創(chuàng)建BetaPlugin
這里就不把完整的實(shí)現(xiàn)代碼貼出來,只貼大體的框架:
public class BetaPlugin implements Plugin<Project> {
...
@Override
void apply(Project project) {
...
}
...
}
創(chuàng)建一個(gè)Plugin就需要實(shí)現(xiàn)Plugin接口场仲,并且重寫它的apply方法和悦,這個(gè)類當(dāng)中就是用來實(shí)現(xiàn)插件的邏輯的,比如創(chuàng)建task渠缕,獲取外部的參數(shù)都需要在這里面完成鸽素。
代碼開發(fā)完畢之后,在resources/META-INF/gradle-plugins目錄下新建一個(gè)properties文件亦鳞,注意該文件的命名就是你使用插件的名字馍忽,這里命名為com.tencent.bugly.plugin.betauploader.properties砰碴,在里面輸入:
implementation-class=com.tencent.bugly.plugin.BetaPlugin
這樣就完成插件的配置了靠欢。
步驟4:接收外部參數(shù)
apply plugin: 'com.tencent.bugly.plugin.betauploader' // 應(yīng)用上傳apk插件
// beta配置
beta {
appId = '900037672'
appKey = 'bQvYLRrBNiqUctfi'
title = "測試"
desc = "beta apk uploader "
enable = true
autoUpload = false
debugOn = false
}
基本上插件的使用就是這樣侦鹏,beta包含的配置都是用戶設(shè)置讓我們插件接收的外部參數(shù)册赛,每個(gè)參數(shù)基本以key = value的形式設(shè)置谁不。
要實(shí)現(xiàn)接收外部參數(shù)就需要自定義一個(gè)定義外部參數(shù)的類坐梯,如下所示:
package com.tencent.bugly.plugin
/**
* Beta extension params
* @author wenjiewu
*/
public class BetaExtension {
public String appId = null // AppID 【必選】
public String appKey = null // AppKey 【必選】
// 【option】
// 【接口參數(shù)】
public String title = null // 標(biāo)題
public String desc = null // 版本描述
public int secret = 1 // 公開范圍(1:所有人,2:密碼刹帕,4管理員吵血,5QQ群,6白名單)
public String users = null // 如果公開范圍是"QQ群"填QQ群號偷溺;如果公開范圍是"白名單"填QQ號碼蹋辅,并使用;切分開,5000個(gè)以內(nèi)挫掏。其他場景無需設(shè)置
public String password = null // 密碼(如果公開范圍是"密碼"需設(shè)置)
public int download_limit = 1000 // 下載上限(大于0侦另,默認(rèn)1000)
public String expId = null // 需替換安裝包的版本id
// 【插件配置】
public String apkFile = null // 指定上傳的apk文件
public Boolean enable = true // 插件開關(guān)
public Boolean autoUpload = false // 是否自動(dòng)上傳
public Boolean debugOn = false // debug模式是否上傳
}
這些參數(shù)都是可以讓用戶配置的。
在插件里面尉共,我們可以通過下面這種方式取得參數(shù)的值:
// 接收外部參數(shù)
project.extensions.create("beta", BetaExtension)
def appId = project.beta.appId
...
步驟5: 創(chuàng)建Task
我們最終要實(shí)現(xiàn)的是通過task能夠?qū)pk文件上傳到bugly平臺(tái)褒傅,代碼實(shí)現(xiàn)如下:
/**
* 創(chuàng)建上傳任務(wù)
*
* @param variant 編譯參數(shù)
* @return
*/
private Task createUploadTask(Object variant) {
String variantName = variant.name.capitalize()
Task uploadTask = project.tasks.create("upload${variantName}BetaApkFile") << {
// if debug model and debugOn = false no execute upload
if (variantName.contains("Debug") && !project.beta.debugOn) {
println("Bugly: the option debugOn is closed, if you want to upload apk file on debug model, you can set debugOn = true to open it")
return
}
uploadApk(generateUploadInfo(variant))
}
println("Bugly:create upload${variantName}BetaApkFile task")
return uploadTask
}
更加具體的代碼細(xì)節(jié),大家可以可以看我開源的代碼袄友。
發(fā)布到JCenter
插件開發(fā)完畢之后殿托,就可以通過gradle腳本將開發(fā)好的代碼打包上傳到JCenter,基本上步驟跟上傳Library是類似的剧蚣,完整代碼如下:
apply plugin: 'com.jfrog.bintray'
apply plugin: 'maven-publish'
group = "com.tencent.bugly.plugin"
version = "1.0.2"
def baseUrl = 'https://github.com/BuglyDevTeam'
def siteUrl = baseUrl
def gitUrl = "${baseUrl}/BuglyBetaUploder.git"
def issueUrl = "${baseUrl}/BuglyBetaUploder/issues"
def projectName = "betauploader"
def mavenDesc = 'bugly beta uploader'
def licenseIds = ['Apache-2.0']
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom.project {
// packaging 'jar'
// Add your description here
name = 'Upload apk file to bugly platform'
url siteUrl
// Set your license
licenses {
license {
name = 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id 'YOUR_ID'
name 'YOUR_NAME'
email 'YOUR_EMAIL'
}
}
scm {
connection gitUrl
developerConnection gitUrl
url siteUrl
}
}
}
}
task sourcesJar(type: Jar) {
from 'src/main/groovy'
exclude 'META-INF'
classifier = 'sources'
}
groovydoc {
includePrivate = true
source = 'src/main/groovy'
}
task groovydocJar(type: Jar, dependsOn: groovydoc) {
classifier = 'javadoc'
from groovydoc.destinationDir
}
artifacts {
archives groovydocJar
archives sourcesJar
}
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
bintray {
user = properties.getProperty("bintray.user")
key = properties.getProperty("bintray.apikey")
configurations = ['archives']
pkg {
repo = 'maven'
name = projectName
desc = mavenDesc
websiteUrl = siteUrl
issueTrackerUrl = issueUrl
vcsUrl = gitUrl
labels = ['gradle', 'com.tencent.bugly.plugin', 'betauploader']
licenses = licenseIds
publish = true
publicDownloadNumbers = true
}
}
至此支竹,插件就已經(jīng)開發(fā)完畢啦,通過gradle bintrayUpload的命令將插件上傳到bintray中的maven倉庫鸠按,然后添加到JCenter倉庫審核即可礼搁。
具體的使用方法,可以參考:https://bugly.qq.com/betaGradle
最后
關(guān)于Gradle插件的開發(fā)也告一段落啦目尖,相對來說這個(gè)插件的功能還比較單一叹坦,更加復(fù)雜的插件開發(fā)可以參考其他開源的項(xiàng)目,只要多查多實(shí)踐卑雁,相信開發(fā)一個(gè)你自己的插件并不是一件很難的事募书。