5

Gradle自动打包APK上传到蒲公英

 2 years ago
source link: http://www.androidchina.net/12488.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Gradle自动打包APK上传到蒲公英 – Android开发中文站

你的位置:Android开发中文站 > 热点资讯 > Gradle自动打包APK上传到蒲公英



一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情

目前所在的公司,没有搭建jekins等自动构建平台,导致每次测试的时候,都需要开发人员手动将debug、release等环境的包手动上传到蒲公英上面,而且因为包名需要保持一致的原因,甚至需要多个蒲公英账号之间来回切换才能完成这项工作,在这个过程中,难免会耽误大量切换时间,以及减少开发效率。甚至在这个过程中,很有可能会因为某些原因导致上传错误。这对于整个团队之间的效率是有极大影响的。 因此,将这个过程转成自动构建的方式也就有极大的意义,在无形之间也将开发人员的效率进行了一个提高。

通过gradle的task可以实现这个功能,当然也可以使用plugin的方式来进行集成、以及多样化配置,但考虑到同事之间可能对这块不是都很熟悉,目前我所展示的方式是使用新建一个gradle文件的方式来进行配置

import groovy.json.JsonSlurper

/**
 * 上传apk到蒲公英
 */
def uploadApk(boolean isRelease) {
    //查找上传的apk文件
    def apkPath = ""
    if (isRelease) {
        apkPath = "app/build/intermediates/apk/release"
    } else {
        apkPath = "app/build/intermediates/apk/debug"
    }

    def apkDir = new File(apkPath)
    if (!apkDir.exists()) {
        throw new RuntimeException("apk output path not exists!")
    }

    def apk = null
    for (int i = apkDir.listFiles().length - 1; i >= 0; i--) {
        File file = apkDir.listFiles()[i]
        if (file.name.endsWith(".apk")) {
            apk = file
            break
        }
    }
    if (apk == null) {
        throw new RuntimeException("apk file not exists!")
    }

    println "*************** start upload file ***************"

    def twoHyphens = "--"
    def boundary = "*********"
    def end = "\r\n"

    //模拟表单上传 multipart/form-data
    def conn = new URL("https://www.pgyer.com/apiv2/app/upload").openConnection()
    conn.setRequestMethod('POST')
    conn.setRequestProperty("Connection", "Keep-Alive")
    conn.setRequestProperty("Charset", "UTF-8")
    conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary)
    conn.setDoInput(true)
    conn.setDoOutput(true)

    def apiKey = ""
    if (isRelease) {
        apiKey = "正式环境apikey"
    } else {
        apiKey = "非正式环境apikey"
    }

    //添加参数:_api_key
    def sb = new StringBuilder()
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=_api_key")
    sb.append(end).append(end)
    sb.append(apiKey).append(end)

    //添加参数:buildUpdateDescription 更新日志,取值git
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=buildUpdateDescription")
    sb.append(end).append(end)
    sb.append(getGitVersionInfo()).append(end)

    //添加参数:buildInstallType 设置安装方式,1为公开方式安装,具体的安装类型参考蒲公英api网址
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=buildInstallType")
    sb.append(end).append(end)
    sb.append(1).append(end)

    //添加参数:buildPassword 设置密码
//    sb.append(twoHyphens).append(boundary).append(end)
//    sb.append("Content-Disposition: form-data; name=buildPassword")
//    sb.append(end).append(end)
//    sb.append("1024").append(end)

    //添加参数file: 需要上传的apk文件
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=file;filename=").append(apk.getName())
    sb.append(end).append(end)

    def dos = new DataOutputStream(conn.getOutputStream())
    dos.writeBytes(sb.toString())
    dos.flush()
    sb.delete(0, sb.length())

    def fis = new FileInputStream(apk)
    byte[] bf = new byte[8192]
    int len
    while ((len = fis.read(bf)) != -1) {
        dos.write(bf, 0, len)
    }
    sb.append(end)
    sb.append(twoHyphens).append(boundary).append(end)
    dos.writeBytes(sb.toString())

    dos.flush()
    fis.close()
    dos.close()
    conn.connect()

    def text = conn.getContent().text
    def resp = new JsonSlurper().parseText(text)

    println text
    println "*************** upload finish ***************"

    if (resp.code != 0) {
        throw new RuntimeException(resp.message)
    }

    //浏览器中打开短连接
    def url = "https://www.pgyer.com/" + resp.data.buildShortcutUrl
    print("上传成功,应用链接:" + url)

}

static def getGitVersionInfo() {
    //获取最新commit id
    def commitId = 'git rev-parse HEAD'.execute().text.trim()
    //获取一条日志
    def logTxt = 'git log - --pretty=format:“%s” ' + commitId
    def log = logTxt.execute().text.trim()
    return log
}

//打包测试环境apk 上传蒲公英 发送邮件功能使用蒲公英自带的邮件功能
task uploadReleaseApk(group: "upload") {
    dependsOn("assembleRelease")

    doLast {
        uploadApk(true)
    }
}

//打包测试环境apk 上传蒲公英 发送邮件功能使用蒲公英自带的邮件功能
task uploadDebugApk(group: "upload") {
    dependsOn("assembleDebug")
    doLast {
        uploadApk(false)
    }
}

在App的build.gradle中加入

apply from: "../uploadReleaseApk.gradle"

image.png

gradle是一个很强大的构建工具,它有很多的功能可以给开发提供很多的便利性,目前我对它的了解还不是很多,但是也从中学习到了很多优秀的功能。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK