gradle实现一键编译并上传蒲公英
序言
使用gradle实现一键编译并上传蒲公英其实网上有很多教程,甚至蒲公英官方API文档 都有对应的教程来教大家怎样搭建。只是无论是网上的教程还是官方的教程,一般来说拿来直接用都会有这样或者那样的问题,我这这篇文章主要的想法还是为了以后避免再遇到坑吧。
正文
gradle主要是用groovy语言来编写的,而对应经常写java语言的朋友们来说,乍一看有点不习惯,看不懂也很正常,如果写过kotlin的话读起来就比较简单了,两者语法上有一定程度上的类似。
官方文档是用PHP语言大致写了一个流程,但对于我这移动端大佬来说,PHP看着有点费劲。但既然是大佬,那肯定得用自己熟悉的语言写出来一个嘛。准备工作
无论搞什么,我们还是得先看一遍官方文档。
常规参数
常规参数里有四个参数,必填参数是_api_key
,这个参数直接点击获取就行,一个账户默认这个值是固定的。
如果一个账户里有多个app,那么可以选择填写appkey
来区分上传的组,也可以不填写,服务器会根据上传的app类型以及包名来区分归属。不过我个人建议还是填上这个值。
上传文件嘛,肯定是post请求了,另外要注意是enctype
为multipart/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"
,等待编译完成后,找到这个命名:
直接执行即可开始编译-->上传。