Gradle插件開發(fā)-上傳apk文件到Bugly

前言

上一篇文章已經(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插件

你可以看到我們在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)建:

  1. 創(chuàng)建一個(gè)Android項(xiàng)目
  2. 新建一個(gè)module炕贵,選擇Androd Library
  3. 刪除除build.gradle之外的所有文件
  4. 按照Groovy工程模板創(chuàng)建對應(yīng)的目錄

最終創(chuàng)建出來的工程如下圖所示:

betauploader

第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ā)布到自己指定的目錄下即可客冈。

uploadArchives

執(zhí)行uploadArchives這個(gè)task旭从,就會(huì)在repo目錄下生成指定版本的插件:

gradle插件生成

步驟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è)你自己的插件并不是一件很難的事募书。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市测蹲,隨后出現(xiàn)的幾起案子莹捡,更是在濱河造成了極大的恐慌,老刑警劉巖扣甲,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件篮赢,死亡現(xiàn)場離奇詭異齿椅,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)启泣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門涣脚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人寥茫,你說我怎么就攤上這事遣蚀。” “怎么了纱耻?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵芭梯,是天一觀的道長。 經(jīng)常有香客問我弄喘,道長玖喘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任蘑志,我火速辦了婚禮累奈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘急但。我一直安慰自己费尽,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布羊始。 她就那樣靜靜地躺著旱幼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪突委。 梳的紋絲不亂的頭發(fā)上柏卤,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音匀油,去河邊找鬼缘缚。 笑死,一個(gè)胖子當(dāng)著我的面吹牛敌蚜,可吹牛的內(nèi)容都是我干的桥滨。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼弛车,長吁一口氣:“原來是場噩夢啊……” “哼齐媒!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纷跛,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤喻括,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后贫奠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體唬血,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡望蜡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拷恨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脖律。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖腕侄,靈堂內(nèi)的尸體忽然破棺而出小泉,到底是詐尸還是另有隱情,我是刑警寧澤兜挨,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站眯分,受9級特大地震影響拌汇,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜弊决,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一噪舀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧飘诗,春花似錦与倡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至溉潭,卻和暖如春净响,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喳瓣。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工馋贤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人畏陕。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓配乓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惠毁。 傳聞我的和親對象是個(gè)殘疾皇子犹芹,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,104評論 25 707
  • 轉(zhuǎn)載注明出處:http://www.reibang.com/p/5255b100930e 0. 前言 完全由個(gè)人翻...
    王三的貓阿德閱讀 2,516評論 0 4
  • Groovy :是一種動(dòng)態(tài)語言。 1:這種語言比較有特點(diǎn)鞠绰,它和 Java 一樣羽莺,也運(yùn)行于 Java 虛擬機(jī)中。簡單...
    PeytonWu閱讀 1,556評論 0 1
  • 向往著一場滂沱大雨 可以湮沒所有的痕跡 天地像混沌初開般 渾然一體 不曾有過任何人的來去 云天下默然佇立 任世間何...
    長山n閱讀 249評論 1 2
  • 開車的都會(huì)有這么一個(gè)感覺荒给!特別討厭路上那些騎電動(dòng)車、騎自行車的刁卜。因?yàn)樗齻兙拖裼芯艞l命似的志电,騎個(gè)車子在大馬路...
    A低調(diào)閱讀 1,188評論 12 6