本方案涉及到的知识点:
1.python基本知识的使用,如:http请求库requests的使用
2.gradle 的基本知识,做过android开发的相信对这一块不陌生,这里只需要了解基本的task创建即可,如果对gradle感兴趣建议系统看下gradle与groovy方面的知识。
3.在tomcat平台下使用java解析上传的文件
4.生成二维码的工具。
方案详细设计:
1.目前android studio开以的项目采用的gradle进行编译的,通常一个项目编译配置文件如下 :
apply plugin: 'com.android.application' android { compileSdkVersion 25 buildToolsVersion "25.0.2" defaultConfig { applicationId "com.baize.autobuild" minSdkVersion 15 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } task uploadApk { def upUrl = "http://localhost:8080/netTest/upload.jsp" def apkPath = "D:/demo/AutoBuild/app/build/outputs/apk/app-debug.apk" //执行Python脚本 def process = "python autobuild.py ${upUrl} ${apkPath}".execute() println("开始上传至fir") //获取Python脚本日志,便于出错调试 ByteArrayOutputStream result = new ByteArrayOutputStream() def inputStream = process.getInputStream() byte[] buffer = new byte[1024] int length while ((length = inputStream.read(buffer)) != -1) { result.write(buffer, 0, length) } println(result.toString("UTF-8")) println "上传结束 " } } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations' }) compile 'com.android.support:appcompat-v7:25.3.1' compile 'com.android.support.constraint:constraint-layout:1.0.2' testCompile 'junit:junit:4.12' }
里面的配置的诸如:依赖包,引用插件机制等这些可以放一边,了解即可。
但是有一个地方需要注意,也是这个方案的核心地方,下面红色框住的地方:
这个task的意图:
将编译好的的apk上传的服务器中去
上传的方式为执行python脚本
注意python脚本为:
# coding=utf-8 # encoding = utf-8 import requests import sys class buildTool(object): url = 'http://localhost:8080/netTest/index.jsp' apkUrlTest = 'http://localhost:8080/netTest/upload.jsp' apkPathTest = ur'test123.apk' """docstring for ClassName""" def __init__(self): super(buildTool,self).__init__() def testGet(self): requestParams = {'username':"liubaize","pwd":"123456789"} try: result = requests.get(url = self.url,params = requestParams) result.encoding = "utf-8" print "19--------------get inputstream from server:",result.text print "21--------------get byte from server:",result.content print "22--------------get json from server:",result.json() print "23--------------get status_code from server:",result.status_code except Exception as e: print '25--------------get request error:',e def uploadApk(self): if len(sys.argv) <= 2: return apkServerUrl = sys.argv[1] apkPath = sys.argv[2] print'36-------------------:',apkPath print '37------------------:',apkServerUrl try: file = {'file': open(apkPath, 'rb')} req = requests.post(url= apkServerUrl, files=file) print '40---------------:upload result:',req.text except Exception as e: print'41---------------upload apk error:',e if __name__ == '__main__': mAndroidBuild = buildTool() mAndroidBuild.uploadApk()
文件放在项目的根目录下,注意你的开发环境是否已经安装了requests库
服务器解析上传文件采用的是java开发,因为比较简单,直接给出源码吧:
package netTest; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.util.Iterator; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.DiskFileUpload; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @SuppressWarnings({ "deprecation", "serial" }) public class FileUpload { public FileUpload() { super(); } public void doGet(HttpServletRequest request, HttpServletResponse response) { try { doPost(request, response); } catch (ServletException e) { System.out.println("PicUpload......doGet......" + e.toString()); } catch (IOException e) { System.out.println("PicUpload......doGet2......" + e.toString()); } } /** * 使用Apache文件上传组件处理文件上传步骤: * 1、创建一个DiskFileItemFactory工厂 * 2、创建一个文件上传解析器 * 3、判断提交上来的数据是否是上传表单的数据 * 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项 * @param request * @param response * @throws ServletException * @throws IOException */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String savePath = request.getSession().getServletContext().getRealPath("/upload"); File file = new File(savePath); if (!file.exists() && !file.isDirectory()) { file.mkdir(); } String message = ""; try { DiskFileItemFactory factory = new DiskFileItemFactory(); // 1、创建一个DiskFileItemFactory工厂 ServletFileUpload upload = new ServletFileUpload(factory); // 2、创建一个文件上传解析器 upload.setHeaderEncoding("UTF-8"); if (!ServletFileUpload.isMultipartContent(request)) { // 3、判断提交上来的数据是否是上传表单的数据 return; } List<FileItem> list = upload.parseRequest(request); // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项 for (FileItem item : list) { if (item.isFormField()) {// 如果fileitem中封装的是表单输入项的数据 String name = item.getFieldName(); String value = item.getString("UTF-8"); System.out.println("上传的文件名为:" + name + "=" + value); } else { // 如果fileitem中封装的是上传文件 String filename = item.getName(); System.out.println("上传的文件名为:" + filename); if (filename == null || filename.trim().equals("")) { continue; } filename = filename.substring(filename.lastIndexOf("\\") + 1); InputStream in = item.getInputStream(); FileOutputStream out = new FileOutputStream(savePath + "\\"+ filename); byte buffer[] = new byte[1024]; int len = 0; while ((len = in.read(buffer)) > 0) { out.write(buffer, 0, len); } in.close(); out.close(); item.delete(); message = "文件上传成功!"; PrintWriter pw=response.getWriter(); pw.write("upload success!!"); pw.flush(); pw.close(); System.out.println(message); } } } catch (Exception e) { message = "文件上传失败!"; e.printStackTrace(); } /*request.setAttribute("message", message); request.getRequestDispatcher("/message.jsp").forward(request, response);*/ } public void init() throws ServletException { // Put your code here } }
上面几个都配置好的话,在编译apk的时候,在控制台就是出现如下:
最后用一个二维码把这个apk的url地址呈现给测试即可
到这一步,一个简单的自动打包测试方案就出炉了
附:
在gradle中编译也是按照task 有序执行的
Android task 简单介绍
Android plugin继承基础task并实现他们的行为。这是在Android环境中task所做的事情:
-assemble:为每一个build类型创建APK;
-clean:移除所有build产品,例如APK文件;
-check:实现lint检测,如果lint检测到问题放弃build;
-build:运行assemble和check;