基于Gradle支持Android Studio的蒲公英自动上传task

版权声明:本文为博主原创文章,未经博主允许不得转载。 - long for us https://blog.csdn.net/longforus/article/details/81104593

最近的项目中在使用蒲公英作为面向客户的App预览平台,虽然没有Jenkins这么强大,但是面向客户的话还是很方便的.但是在使用的过程中,需要到网页手动上传不是很方便,蒲公英都相应的Api接口,可以进行上传操作,我就想是需要一个快捷上传的方式了.

实现思路

Android Studio使用Gradle作为构建工具,Gradle的功能是十分强大的,可以自定义Plugin hook构建过程中的各个阶段.今天的任务比较简单,不用单独写插件那么麻烦,就写一个task就可以了.

实现过程

获取apk路径

既然要上传apk,那不管怎么样首先肯定是要得到apk文件了.在android插件的配置闭包中我们可以通过下面的方式拿到输出的apk文件.

applicationVariants.all {
                        it.outputs.each { out ->
                            def outputFile = out.outputFile
                            if (outputFile != null && outputFile.name == 'app-debug.apk') {
                               //在这里outputFile就是debug生成的apk了
                            }
                        }
                    }

调用接口进行上传

  • 在.gradle文件中可以直接调用的网络库是java.net.HttpURLConnection,我很久没用过了,感觉用起来也不是很方便,于是就想使用熟悉一点点的OkHttp来进行上传操作.但是OkHttp不是java自带的库,默认在.gradle文件中是无法调用的,怎么才能在.gradle文件中引用第三方库呢?答案是加入classpath引入:

    import okhttp3.OkHttpClient//2.导入
    
    buildscript {
      repositories {
          jcenter()
      }
      dependencies {
          classpath 'com.squareup.okhttp3:okhttp:3.11.0'//1.添加依赖
      }
    }
    
    OkHttpClient client = new OkHttpClient()//3.可以用了

    引入了网络库,开搞吧.

    URL url = new URL('https://www.pgyer.com/apiv2/app/upload')
    MediaType type = MediaType.parse("multipart/form-data")
    OkHttpClient client = new OkHttpClient()
    def build = new MultipartBody.Builder()
    build.addFormDataPart("file", outputFile.getName(), RequestBody.create(MediaType.parse('"application/octet-stream"'), outputFile))
    build.addFormDataPart("_api_key", "_api_key_api_key_api_key")
    build.addFormDataPart("userKey", "userKeyuserKeyuserKey")
    build.addFormDataPart("buildUpdateDescription", "uat服务器 debug")
    def body = build.build()
    logger.log(LogLevel.ERROR, "upload scusses : ${body.toString()}")
    Request request = new Request.Builder()
       .url(url)
       .addHeader("_api_key", "_api_key_api_key_api_key")
       .post(body)
       .build()
    
    Response response = client.newCall(request).execute()
    if (response.isSuccessful()) {
            logger.log(LogLevel.ERROR, "upload scusses : ${response.body().string()}")
            } else {
             logger.log(LogLevel.ERROR, "upload failure : ${response.message()}")
     }

    以为这样就好了?我也是这么以为,但是上传服务器都提示我_api_key未配置,但是我明明的配置了的呀,不管我把_api_key addFormDataPart() 还是addHeader() 都是一样的,直到我把它作为Query进行拼接.https://www.pgyer.com/apiv2/app/upload?_api_key=_api_key_api_key_api_key 这样才没有再报 _api_key未配置的问题,但是新的问题是说我的apk文件为null.这样我就比较无语了,不知道是我的写法有问题还是他们的后台有问题.

  • 在OkHttp行不通以后本来想用HttpURLConnection再行尝试,但是我注意到蒲公英的Api中说可以使用curl进行上传,curl我在用Linux的时候也用过几次,几乎的陌生的.但是我知道它很强大.百度百科:curl是利用URL语法在命令行方式下工作的开源文件传输工具。它被广泛应用在Unix、多种Linux发行版中,并且有DOS和Win32、Win64下的移植版本。(我的win10已经有curl了,可能是装Git的时候一起装的,如果你的电脑没有安装的话,请百度安装.)curl是一个命令行的工具,在Android Studio中怎么调用呢?当然是使用java.lang.Runtime类了,简单方便.调用如下;

    Runtime runtime = Runtime.getRuntime()
    Process p = runtime.exec(uploadCommand)//执行命令
    InputStream fis = p.getInputStream()
    InputStreamReader isr = new InputStreamReader(fis)
    BufferedReader br = new BufferedReader(isr)
    String line = null
    logger.log(LogLevel.ERROR, "upload result :")
    while ((line = br.readLine()) != null) {//读取结果
       logger.log(LogLevel.ERROR, line)
    }
    br.close()
    isr.close()
    fis.close()

打开结果上传结果页面

上传完成后可能想看看效果,或者截取安装二维码发送给客户,这时候需要打开上传结果页面,上传的接口返回了这个页面的短连接,拼接一下就能得到地址,再调用Runtime打开浏览器就ok了,so easy.

  String sUrl = line.substring(start, end)
  runtime.exec("cmd   /c   start  https://www.pgyer.com/$sUrl")

优化

经过上面的步骤,上传就完成了,但是现在这个task是写在app模块的build.gradle文件中的,如果别的项目要使用需要复制修改,而且也让这个这个文件显得比较繁杂.现在可以优化的是把这个上传任务从这个文件中抽取出来,单独放到一个文件中.方便复用,整洁代码.这个用到的是gradle的脚本插件功能.

  • 在工程根目录新建一个dandelionUpload.gradle文件,把task拷贝到里面.

  • 然后在app模块的build.gradle文件中引用这个脚本插件.

    apply from: "${rootProject.rootDir}/dandelionUpload.gradle" //引入
    android {
      ......
      project.ext.upload2d project,"这里是上传的描述"//引用插件并传入参数
    }

这样就达到了方便复用的目的,同时也保持了app模块的build.gradle文件的清爽.

使用

添加完成task,同步过后,在

up1

这里会出现一个任务点击一下就OK了.
up2

这个任务默认上传的是debug模式下的包(你如果要上传别的包请自行修改),因为依赖于assembleDebug任务,如果包不存在的话会调用assembleDebug进行构建,完成后上传.

完整代码在这里,东西很简单,但是还算有用吧.如果对你有帮助欢迎star,你的star是我的动力.

猜你喜欢

转载自blog.csdn.net/longforus/article/details/81104593
今日推荐