zoukankan      html  css  js  c++  java
  • 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 
    
    ";
        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);
                // 把'
    '换行符换成网页中的换行符<br />
                if (ch == '
    ')
                {
                    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最后会被移动到该文件夹下。
    这里写图片描写叙述

    最后,渠道包生成完毕后,点击链接。浏览器跳转到渠道包列表网页下载渠道包。

    相关文章

    1.Ant开发总结
    2.CGI编程

    项目地址:https://coding.net/u/linchaolong/p/BSBatchPkgTool/git

  • 相关阅读:
    欧拉回路 定理
    UESTC 1087 【二分查找】
    POJ 3159 【朴素的差分约束】
    ZOJ 1232 【灵活运用FLOYD】 【图DP】
    POJ 3013 【需要一点点思维...】【乘法分配率】
    POJ 2502 【思维是朴素的最短路 卡输入和建图】
    POJ 2240 【这题貌似可以直接FLOYD 屌丝用SPFA通过枚举找正权值环 顺便学了下map】
    POJ 1860【求解是否存在权值为正的环 屌丝做的第一道权值需要计算的题 想喊一声SPFA万岁】
    POJ 1797 【一种叫做最大生成树的很有趣的贪心】【也可以用dij的变形思想~】
    js 实现slider封装
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7363109.html
Copyright © 2011-2022 走看看