AndroidAndroid

gradle实现一键编译并上传蒲公英

2020-08-24  本文已影响0人  海阔sun天空

序言

使用gradle实现一键编译并上传蒲公英其实网上有很多教程,甚至蒲公英官方API文档 都有对应的教程来教大家怎样搭建。只是无论是网上的教程还是官方的教程,一般来说拿来直接用都会有这样或者那样的问题,我这这篇文章主要的想法还是为了以后避免再遇到坑吧。

正文

gradle主要是用groovy语言来编写的,而对应经常写java语言的朋友们来说,乍一看有点不习惯,看不懂也很正常,如果写过kotlin的话读起来就比较简单了,两者语法上有一定程度上的类似。

官方文档是用PHP语言大致写了一个流程,但对于我这移动端大佬来说,PHP看着有点费劲。但既然是大佬,那肯定得用自己熟悉的语言写出来一个嘛。

准备工作

无论搞什么,我们还是得先看一遍官方文档。


常规参数

常规参数里有四个参数,必填参数是_api_key,这个参数直接点击获取就行,一个账户默认这个值是固定的。
如果一个账户里有多个app,那么可以选择填写appkey来区分上传的组,也可以不填写,服务器会根据上传的app类型以及包名来区分归属。不过我个人建议还是填上这个值。

上传参数

上传文件嘛,肯定是post请求了,另外要注意是enctypemultipart/form-data,不熟悉HTTP协议的可能会问,enctype是啥呢?

enctype 属性规定在发送到服务器之前应该如何对表单数据进行编码。

除了_api_key为必选之外,还有俩参数需要额外注意下,file-->文件,buildInstallType-->按照方式。一般我们用蒲公英都是测试分发,那最少也得密码安装吧,所以这个值基本是必填的,同样还有下面的buildPassword-->安装密码,总共五个参数需要注意。

实操

首先要创建gradle脚本文件,直接在跟目录下创建uploadPger.gradle

获取要上传app的详细地址:

def getApkPath() {
    String buildType = getBuildType().toLowerCase()
    return new File(buildDir, "outputs/apk/${buildType}/app-${buildType}.apk").absolutePath
}

这个方法基本可以满足获取app目录,但对于有些朋友在app打包的时候给app重命名,比如加上时间等等用以区分不同时间点打出的app,这个办法就不行了。
那么我们要稍加改造一下:
首先我们要有一个字段来记录想要上传app的名称,在项目的build.gradle添加:

ext{
     debugApkFile = ""
}

然后我们要在打包命名的地方进行记录:

applicationVariants.all { variant ->
                variant.outputs.all {
                    // 输出apk名称  
                    def fileName = "" 
                    outputFileName = fileName
                    if (fileName.contains("debug")){
                        rootProject.ext.debugApkFile = fileName
                        // 打印
                        println "domestic debug apkName:"+rootProject.ext.debugApkFile
                    }
                }
            }

我们这只是举例记录debug包,这样app的名称就记录下来了。接下来改造下

def getApkPath() {
    String buildType = getBuildType().toLowerCase()
    return new File(buildDir, "outputs/apk/${buildType}/" + rootProject.ext.debugApkFile).absolutePath
}

接下来开始撸上传方法,直接上代码:

def uploadApk() {
    def debugApkFile = getApkPath()
    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)//可以允许若干 控件域 同时上传其值,每个域值使用 boundary 分割
    conn.setDoInput(true)
    conn.setDoOutput(true)

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

    // 添加参数 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("你自己的api_key").append(end)

    //添加 app_key
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=app_key")
    sb.append(end).append(end)
    sb.append("需要上传的appKey").append(end)

    //添加参数:buildInstallType 设置密码安装
    sb.append(twoHyphens).append(boundary).append(end)
    sb.append("Content-Disposition: form-data; name=buildInstallType")
    sb.append(end).append(end)
    sb.append(2).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("自己设置的密码").append(end)

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

    println "===========参数============" + sb.toString()

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

    def fis = new FileInputStream(debugApkFile)
    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 resp
    println "*************** upload finish ***************"

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

}

这一套的写法大同小异,网上的都差不多。最后加一个task:

task uploadApk(group: "upload") {
    dependsOn("assembleDebug")
    // 等待编译完成后再执行上传操作
    doLast {
        uploadApk()
    }
}

都编写完,开始导入,在app的build.gradle下添加我们的这个文件
apply from: "../uploadPger.gradle" ,等待编译完成后,找到这个命名:


直接执行即可开始编译-->上传。

结语

又多了一个装逼的技能。
上一篇下一篇

猜你喜欢

热点阅读