B/S模式实现批量打包apk
界面流程
界面例如以下: 
 
这是一个使用html编写的界面,界面分为两半。两个frame。左边为操作栏,右边为控制台输出。
打包流程: 
选择须要打包的渠道后,点击打包,等待server打包,并把日志输出到右边的frame。
打包完毕后。点击”点击打开下载界面”链接。跳转到下载界面。
实现思路
环境说明
server使用的是apache server2.4.12,所以与浏览器的交互是使用cgi,关于cgi能够參考这里。 
自己主动化的实现使用ant。关于ant能够參考这里。
开发工具:vs2013 
开发语言:html、javascript、C++ 
系统:win7 x64
浏览器与服务端的交互。
服务端结构: 
在主界面左边的frame中有一个渠道列表,每一个渠道相应一个id。
<fieldset align="left" >
            <legend>渠道列表:</legend>
            <label class="labelChnnel">Debug<input class="btnChnnel" name="chnnel" type="checkbox" value="1" /></label>
            <label class="labelChnnel">小米<input class="btnChnnel" name="chnnel" type="checkbox" value="2" /></label>
            <label class="labelChnnel">360<input class="btnChnnel" name="chnnel" type="checkbox" value="3" /></label>
            <label class="labelChnnel">安智<input class="btnChnnel" name="chnnel" type="checkbox" value="4" /></label>
            <label class="labelChnnel">应用汇<input class="btnChnnel" name="chnnel" type="checkbox" value="5" /></label>
            <label class="labelChnnel">中国移动<input class="btnChnnel" name="chnnel" type="checkbox" value="6" /></label>
            <label class="labelChnnel">中国联通<input class="btnChnnel" name="chnnel" type="checkbox" value="7" /></label>
            <label class="labelChnnel">中国电信<input class="btnChnnel" name="chnnel" type="checkbox" value="8" /></label>
            <label class="labelChnnel">九游<input class="btnChnnel" name="chnnel" type="checkbox" value="9" /></label>
        </fieldset>
当点击打包的时候,会先获取当前选择的全部的渠道id并连接成一个字符串。
// 获取选择的渠道列表
    function getChnnelList()
    {
        //getElementsByTagName:依据标签名获取元素集合
        //getElementById:依据id获取元素
        //getElementsByName:依据名称(name属性值)获取元素集合
        var checkboxes = document.getElementsByName('chnnel');
        var len = checkboxes.length;
        var chnnelList = "";
        for(var i=0; i<len; ++i)
        {
            if(checkboxes[i].checked)
            {
                chnnelList = chnnelList + checkboxes[i].value + " "; //把渠道id连接成字符串
            }
        }
        return chnnelList;
    }
接着调用requestPkg方法并把渠道id字符串传入,该方法会发送一个异步请求到服务端。并把server返回的数据显示在右边的frame中。
// 打包
    function requestPkg( data )
    {
        var img = document.getElementById("loadingImg");
        // 防止连续点击
        if('inline' == img.style.display){
            return
        }
        //显示loading
        showLoading();
        var xmlHttp = new XMLHttpRequest();
        // 1.提交方式(GET/POST)
        // 2.url
        // 3.是否异步
        xmlHttp.open( "POST", "http://localhost/cgi-bin/apkpkg.cgi", true );
        xmlHttp.overrideMimeType('text/plain; charset=gbk'); // 解决frame中文乱码问题
        // response handler
        xmlHttp.onreadystatechange = function () {
            if (xmlHttp.readyState == XMLHttpRequest.DONE) {
                if (xmlHttp.status == 200) {
                    // 把返回数据显示在右边的frame
                    var doc = parent.right_frame.document;
                    //加入html文本
                    var html = doc.createElement("div");
                    html.className = "description";
                    html.innerHTML = xmlHttp.responseText;
                    doc.body.appendChild(html);
                    // 加入普通文本
                    //var txt=doc.createTextNode(xmlHttp.responseText)
                    //doc.body.appendChild(txt)
                    //自己主动向下滚动
                    parent.right_frame.scrollBy(0, html.scrollHeight);
                } else if (xmlHttp.status == 400) {
                    console.log('There was an error 400');
                } else {
                    console.log('something else other than 200 was returned');
                }
                //隐藏loading
                hideLoading();
            }
        };
        // 发送请求
        xmlHttp.send( data );
    }
服务端处理流程例如以下: 
1.服务端接受到渠道id字符串后,对字符串进行切割并转换为整数,加入到chnnelList 
2.然后调用git pull(假设是svn则运行svn update)命令更新project。 
3.迭代chnnelList,依据渠道id运行不同的命令(ant能够把一系列操作简化成运行一个命令。事实上打包的过程。无非是对文件的一些操作。如删除、拷贝、移动、替换文件内容等,或者是运行一些命令,这些都能够通过ant实现,假设真遇到ant库提供的功能实现不了的需求,ant也提供了扩展的接口,详细可參考这里。能够的话也跟我说说吧。
) 
4.输出运行结果。
//main.cpp
#include <stdio.h>
#include <iostream>
#include "cmdlib.h"
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
using namespace std;
//常量
class Constant{
public:
    // project所在文件夹
    static const char* ProjectDir; //声明静态变量
};
// 静态变量的初始化
const char* Constant::ProjectDir = "D:/AndroidDeveloper/workspace2/AntTest";
// 依据渠道id运行不同的命令
void exeCmd(int &id){
    switch (id)
    {
    //Debug
    case 1:
        cmd::exec_atdir(Constant::ProjectDir, "ant buildDebug", true);
        break;
    //小米
    case 2:
        cmd::exec_atdir(Constant::ProjectDir, "ant buildXiaoMi", true);
        break;
    //360
    case 3:
        break;
    //安智
    case 4:
        break;
    //应用汇
    case 5:
        break;
    //中国移动
    case 6:
        break;
    //中国联通
    case 7:
        break;
    //中国电信
    case 8:
        break;
    //九游
    case 9:
        break;
    }
}
void main(){
    cout<<"Context-type:text/html; charset=UTF-8 \n\n";
    cout<<"<html>";
    cout<<"<body>";
    // 获取提交的參数
    char params[256] = { 0 };
    gets_s(params);//获取输入
    cout << "<p>params=" << params << "</p>";
    vector<string> chnnelStrList;
    istringstream iss(params);
    // 对字符串进行切割,并复制到渠道列表
    copy(istream_iterator<string>(iss),             // 開始位置
        istream_iterator<string>(),                 // 结束位置
        back_inserter<vector<string>>(chnnelStrList)); // push_back到vector
    // 把字符串转换成整数
    vector<int> chnnelLlist;
    int chnnel = 0;
    for_each(chnnelStrList.begin(), chnnelStrList.end(), [&chnnel, &chnnelLlist](string & str){
        chnnel = atoi(str.c_str());
        if (chnnel != 0)
        {
            chnnelLlist.push_back(chnnel);
        }
    });
    // 首先更新project
    // svn update / git pull
    cmd::exec_atdir(Constant::ProjectDir, "git pull", false);
    // 依据id运行相应的命令
    for_each(chnnelLlist.begin(), chnnelLlist.end(), [](int & id){
        exeCmd(id);
    });
    cout<<"</body>";
    cout<<"</html>";
}
// cmdlib.h
#ifndef __CMDLIB_H__
#define __CMDLIB_H__
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;
namespace cmd{
    // 运行命令并输出
    bool exec_output(const char* cmd){
        // 运行命令,并打印输出
        FILE* pipe = _popen(cmd, "r"); // 第一个參数是指令字符串。第二个參数是模式(r:读,w:写)
        // _popen函数用于运行一条指令并把结果输出到内存中的文件对象
        if (!pipe)
        {
            return false;
        }
        cout << "<p>";
        // 把运行结果输出到网页
        char ch = 0;
        while (!feof(pipe)){
            ch = fgetc(pipe);
            // 把'\n'换行符换成网页中的换行符<br />
            if (ch == '\n')
            {
                cout<<"<br />";
            }
            else{
                putchar(ch);
            }
        }
        cout << "</p>";
        return true;
    }
    // 在指定文件夹下运行一个命令
    // dir:文件夹路径
    // cmd:命令
    // is_out:是否输出运行结果
    void exec_atdir(const char* dir, const char* cmd, bool is_out = false){
        char buff[1024] = { 0 };
#if _WIN32
        sprintf_s(buff, "cd /d %s & %s", dir, cmd);
#else
        sprintf_s(buff, "cd %s & %s", dir, cmd);
#endif
        if (is_out)
        {
            exec_output(buff);
        }
        else{
            system(buff);
        }
    }
};
#endif
在Apache Server安装文件夹下有一个htdocs文件夹,是站点的根文件夹。我在这里新建了一个apk文件夹。用于存放所以自己主动生成的apk。通过http://localhost/apk(这里的localhost指server的ip。由于我在本地測试所以使用localhost)能够在浏览器訪问该文件夹。
通过ant命令生成的apk最后会被移动到该文件夹下。 
最后,渠道包生成完毕后,点击链接。浏览器跳转到渠道包列表网页下载渠道包。
相关文章
B/S模式实现批量打包apk的更多相关文章
- 整理的Unity导出安卓工程利用ANT进行多渠道批量打包APK
		
Unity导出的安卓工程利用ant进行多渠道循环批量打包 一:设置JAVA环境变量 做android开发的配置这个是基础. win7 下配置java环境变量,下面是链接 http://www.cnbl ...
 - Android 自动编译、打包生成apk文件 4 - 多渠道批量打包
		
相关文章列表: < Android 自动编译.打包生成apk文件 1 - 命令行方式> < Android 自动编译.打包生成apk文件 2 - 使用原生Ant方式 > < ...
 - Android批量打包-如何一秒内打完几百个apk渠道包
		
在国内Android常用渠道可能多达几十个,如: 谷歌市场.腾讯应用宝.百度手机助手.91手机商城.360应用平台.豌豆荚.安卓市场.小米.魅族商店.oppo手机.联想乐商.中兴汇天地.华为.安智.应 ...
 - Unity3D研究院之脚本批量打包渠道包研究
		
原地址:http://www.xuanyusong.com/archives/2418#comments 最近在研究Unity3D脚本批量打包,比如在Android平台下各种不同分辨率和不同内存大小的 ...
 - Unity3D脚本批量打包渠道包
		
最近在研究Unity3D脚本批量打包,比如在Android平台下各种不同分辨率和不同内存大小的机器,可能还有不同的渠道包,不同渠道可能用的SDK都不一样,这一切的一切都表明你的代码无法做到自适应的,除 ...
 - Android Studio 多个编译环境配置 多渠道打包 APK输出配置
		
看完这篇你学到什么: 熟悉gradle的构建配置 熟悉代码构建环境的目录结构,你知道的不仅仅是只有src/main 开发.生成环境等等环境可以任意切换打包 多渠道打包 APK输出文件配置 需求 一般我 ...
 - Unity自动打包 apk
		
1.流程 Unity打包 apk,会把Unity安装目录下的默认 AndroidManifest.Xml 文件覆盖到apk中去,同时还会拷贝该文件所在目录下的其它默认设置文件,如 res 和 asse ...
 - 在Android开发中使用Ant 三:批量打包
		
批量打包最常用到的地方是进行产品推广时,为每个渠道打一个包.上一篇随笔中,介绍了怎样进行一次完整的打包,批量打包只要在此基础上做一次循环即可. 在打包之前要做两个准备工作,一个是读取渠道,一个是修改存 ...
 - Unity自动打包Apk
		
unity打包apk相对来说比较容易,相信出过的人都明白,出包过程,没有大的难度,一步一操作,一步一等待,繁琐耗时,不懂的人又代替不了.这时候需求就来了,如何简单的一键打包搞定,这个就稍微有点难度,当 ...
 
随机推荐
- 开源中国(oschina.net)能给我一个交代吗?
			
一年前准备把goolge上面diocp项目移动到开源中国上面,当时觉得开源中国的的速度还不错,都叫开源中国了,觉得应该稳定. 后来把今年开源mybean项目也放在上面了,还有一些小的项目都放在上面,就 ...
 - js实现类似qq表情(插入图片以及获取光标的效果)
			
<!doctype html><html style="height:100%"><head><meta charset="ut ...
 - 【GitHub】常用命令
			
克隆项目 git clone http://*git 把本地项目提交到远程 git add --all git commit -m "Initail commit" git pus ...
 - Cpu表现出正弦曲线
			
#include <windows.h> #include <math.h> int main(void) { SetThreadAffinityMask(GetCurrent ...
 - Sql server在另一台服务器,在Visual Studio 中没问题,IIS中 提示“在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误。。。。”
			
可能问题一: 确切的说是在IIS 7.5中有这问题 就是在visual studio中都用的好好的,但是加载到IIS上的时候竟然报错“ 在与 SQL Server 建立连接时出现与网络相关的或特定于实 ...
 - ubuntu apt-get 安装指定版本软件
			
有时候 Ubuntu安装软件时候会提示你缺少对应版本的软件,这时候你就需要用到 sudo apt-get install softname=version 来安装对应的软件. sudo apt-get ...
 - C++中嵌入python程序——命令行模式
			
http://blog.csdn.net/yiyouxian/article/details/51992721
 - 01,WP8开发基础
			
1,wp应用程序的生命周期 编写wp程序,首先必须要搞懂程序的生命周期,因为我们需要在这些不同的时间点做一些必要的事情,比如保存和恢复一些数据.下面这几个事件是我们必须关注的. Applicatoin ...
 - 【C】——setvbuf(scanf内存溢出问题)
			
下面设置了一个长度为20的缓存区,循环对value进行赋值并输出: #include<stdio.h> #define BUFSIZE 20 int main(int argc, char ...
 - awk的替代先sort 再uniq -c 再sort  ,uniq只能队相邻的起作用sort先让之间相邻再sort,最后sort是数量排序
			
[root@localhost ~]# cat aa.txt |sort|uniq -c|sort -nk1 1 22\ 1 44 1 55\ 1 bb 1 dd 1 ff 1 gg 1 kk 1 o ...