Android 如何使用ant批量打包
来源:互联网 发布:淘宝买高压气瓶犯法吗 编辑:程序博客网 时间:2024/05/20 22:00
由于公司运维需要,每次上线都需要打几十个市场版的apk文件,主要修改就只有一处,就是manifest中的一个市场标识属性,因为对ant批量打包不了解,一直使用手动打包,感觉既枯燥机械又低效,由于厌倦了手动打包,感觉再有这么多好工具的情况下,居然还手动打apk,未免显的太原始了吧,闲来无事,就研究了一下如何使用ant来批量打apk
因为已经有了使用ant打一个签名apk的基础,见博客http://blog.csdn.net/guonanyun/article/details/7382843(android使用ant自动化打包),所以一开始的想法是使用ant中的循环语法:循环遍历市场标识文件,依次执行相同命令,发现ant似乎对循环命令支持不够,再加上本身对ant不了解,只是或多或少的接触过一些,从来没有深入的研究过,只找到一种在ant中使用javascript语法来实现循环的语法,从网上找的测试程序本身是OK的,但是要想实现我的需求,需要熟悉运用ant api,所以只好作废,此时陷入了僵局
后来突发奇想,既然ant可以调用java代码,那反过来java是不是也也可以调用ant命令呀,不查不知道,一查吓一跳,网上果然有人写出了使用java调用ant脚本http://hilary3113.iteye.com/blog/1155517的博客,似乎看到了胜利的曙光.马上果断的把例子代码粘贴过来,引入相关的jar文件,自己运行一下.发现运行报错,是如下错误信息
E:\other\mapbarmaps_5.6_backup\build.xml:83: import requires support in ProjectHelper(ps:因为我的build.xml文件引入了android自身的build.xml)
后来将该错误信息作为关键字进行google搜索,找到如下博客http://yxhcquedu.iteye.com/blog/861110,也是一个测试demo,拷贝代码并做相应修改,发现出现了新的报错,
com.sun.tools.javac.Main is not on the classpath.
Perhaps JAVA_HOME does not point to the JDK.
It is currently set to "C:/Program Files/Java/jre1.5.0_11"
继续google搜索,发现网上给的比较多的解答是这种方式:http://blog.csdn.net/lhjlhj123123/article/details/5607106,尝试后发现仍然不好使,并且多次确信java环境变量是OK的,后来看了一下java project的依赖jar包,发现都是jre下面lib中的jar文件
说明一下,该图中jdk\lib下的jar包是后来引入的,一开始是没有的
会不是是引入jar包的问题呢?凡事都要尝试一下呀,.实践才是检验真理的唯一标准啊!把C:\Java\jdk1.6.0_21\lib下的jar包引入后,再次运行,OK,虽然还是不明白ant为啥会出现这种问题,但是问题总算是得到了圆满的解决,以后再去知其所以然吧
到此,使用java调用ant脚本打包算是可以正常使用了
下面,就开始考虑如何来批量打包了
首先明确一下项目需求:修改mainfest.xml中的一个属性,打成apk
其次执行步骤依次如下:
1)先修改manifest文件,考虑到若直接把占位符放到manifest文件中,第一次替换成市场标识后,还是需要再替换回占位符的,这相当于多做了一步操作,联想到昨天看的使用ant脚本替换文件中某项的例子,发现先声明一个manifest临时文件,读取该文件中的内容,替换占位符后,将新的内容再次写入manifest中是个不错的方案,尝试一下证明是OK的
ps:上述步骤使用了java中文件操作的相关知识,由于io基础不扎实,为了把重点放到ant打包上,所以继续奉行拿来主义,从网上找了java修改文件内容的相关博客,http://www.iteye.com/problems/56425,直接拷贝代码使用
2)初始化ant项目的相关配置并执行打包命令
3)将打完的apk进行重命名(加入市场标识的后缀)和拷贝操作
4)继续遍历市场标识数组或集合,依次执行步骤1),2),3)
至此,ant批量打包总算是可以正常使用了
如果要抽样测试打出的apk是否已经修改了manifest文件中指定的属性,可以反编译aok后查看,请参考如下博客:
Android APK反编译详解(附图)http://blog.csdn.net/sunboy_2050/article/details/6727581
ps :后期熟悉ant的话,可以使用纯ant脚本或者使用另一种更好的自动化打包工具(maven)
关键代码如下:
package com.cn.ant;import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.File; import java.io.FileReader;import java.io.FileWriter;import java.io.IOException;import java.util.ArrayList;import org.apache.tools.ant.DefaultLogger; import org.apache.tools.ant.Project; import org.apache.tools.ant.ProjectHelper; public class AntTest { private Project project; public void init(String _buildFile, String _baseDir) throws Exception { project = new Project(); project.init(); DefaultLogger consoleLogger = new DefaultLogger(); consoleLogger.setErrorPrintStream(System.err); consoleLogger.setOutputPrintStream(System.out); consoleLogger.setMessageOutputLevel(Project.MSG_INFO); project.addBuildListener(consoleLogger); // Set the base directory. If none is given, "." is used. if (_baseDir == null) _baseDir = new String("."); project.setBasedir(_baseDir); if (_buildFile == null) _buildFile = new String(projectBasePath + File.separator + "build.xml"); //ProjectHelper.getProjectHelper().parse(project, new File(_buildFile)); // 关键代码 ProjectHelper.configureProject(project, new File(_buildFile)); } public void runTarget(String _target) throws Exception { // Test if the project exists if (project == null) throw new Exception( "No target can be launched because the project has not been initialized. Please call the 'init' method first !"); // If no target is specified, run the default one. if (_target == null) _target = project.getDefaultTarget(); // Run the target project.executeTarget(_target); } // private final static ArrayList<String> flagList = new ArrayList<String>(); //也可以使用集合,不过需要手动添加项 private final static String[] flagList = new String[]{"htc","moto","oppo"};//此处初始化市场标识 private final static String projectBasePath = ""; //项目的根目录,需要配置 private final static String copyApkPath = ""; //要改名后拷贝的目录,需要配置 private final static String placeHolder = ""; //占位符,需要配置 public static void main(String args[]) { //flagList.add("htc"); //flagList.add("moto"); //flagList.add("oppo"); try { System.out.println("---------ant批量自动化打包开始----------"); for(String flag : flagList){ //先修改manifest文件:读取临时文件中的@market@修改为市场标识,然后写入manifest.xml中 String tempFilePath = projectBasePath + File.separator + "AndroidManifest.xml.temp"; String filePath = projectBasePath + File.separator + "AndroidManifest.xml"; write(filePath,read(tempFilePath, flag)); //执行打包命令 AntTest mytest = new AntTest(); mytest.init( projectBasePath + File.separator + "build.xml", projectBasePath); mytest.runTarget("clean"); mytest.runTarget("release"); //打完包后执行重命名加拷贝操作 //String flag = "htc"; File file = new File(projectBasePath + File.separator +"bin"+File.pathSeparator+"MainActivity-release.apk");//bin目录下签名的apk文件 file.renameTo(new File(copyApkPath + File.separator + "MainActivity_"+flag+".apk")); } System.out.println("---------ant批量自动化打包结束----------"); } catch (Exception e) { e.printStackTrace(); System.out.println("---------ant批量自动化打包中发生异常----------"); } } public static String read(String filePath,String replaceStr) { BufferedReader br = null; String line = null; StringBuffer buf = new StringBuffer(); try { // 根据文件路径创建缓冲输入流 br = new BufferedReader(new FileReader(filePath)); // 循环读取文件的每一行, 对需要修改的行进行修改, 放入缓冲对象中 while ((line = br.readLine()) != null) { // 此处根据实际需要修改某些行的内容 if (line.contains(placeHolder)) { line = line.replace(placeHolder, replaceStr); buf.append(line); } else { buf.append(line); } buf.append(System.getProperty("line.separator")); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 if (br != null) { try { br.close(); } catch (IOException e) { br = null; } } } return buf.toString(); } /** * 将内容回写到文件中 * * @param filePath * @param content */ public static void write(String filePath, String content) { BufferedWriter bw = null; try { // 根据文件路径创建缓冲输出流 bw = new BufferedWriter(new FileWriter(filePath)); // 将内容写入文件中 bw.write(content); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭流 if (bw != null) { try { bw.close(); } catch (IOException e) { bw = null; } } } } }
- android如何使用ant批量打包
- Android 如何使用ant批量打包
- Android使用Ant批量打包
- Android 使用 Ant 批量打包
- Android使用Ant批量打包
- 使用Ant 实现批量打包Android应用
- 使用 Ant 实现批量打包Android应用
- 使用Ant 实现批量打包Android应用
- 使用Ant 实现批量打包Android应用
- 使用Ant 实现批量打包Android应用
- 使用Ant批量打包Android项目
- 使用Ant批量打包Android应用
- 使用Ant 实现批量打包Android应用
- 使用Ant 实现批量打包Android应用
- 使用Ant批量打包Android渠道包
- android 使用ANT批量打包apk步骤
- android 使用ANT批量打包apk步骤
- Android使用Ant批量打包应用步骤
- hdu3360National Treasures (最大匹配,拆点法)
- 第一章 关键字
- 在JavaScript 调用C++
- 关于linux oss音频应用编程详解,写的挺好的
- 工作随谈之扯淡
- Android 如何使用ant批量打包
- 第一章 数据类型
- Android Application package 'AndroidManifest.xml' must have a minimum of 2 segments.
- http://blog.csdn.net/dm_vincent/article/details/7655764
- 程序员生存定律-选公司前要干的事:分类
- jquery中each用法
- 基于链表的C语言堆内存检测
- 从C调用JavaScript函数代码。
- 检测本机是否登录了指定QQ账号