本方案涉及到的知识点:
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;