2019独角兽企业重金招聘Python工程师标准>>>

由于公司运维需要以及应用中需要加上应用推广的统计,往往要对应二三十个渠道,按照正常方法一个一个的去生成不同渠道包的应用,不仅浪费了时间,而且大大降低了效率.

上一篇讲到使用Ant进行Zip/Tar包的解压缩,实际上Ant工具不仅仅具有此类功能,它更强大的地方在于自动化调用程序完成项目的编译,打包,测试等. 类似于C语言中的make脚本完成这些工作的批处理任务. 不同于MakeFile的是,Ant是纯Java编写的,因此具有很好的跨平台性.

在此我主要讲下如何自动构建工具Ant, 对应用进行批量打包, 生成对应不同市场的应用:

首先分别看一下用于打包的Java工程AntTest和需要被打包进行发布的Android工程结构:

market.txt里保存需要打包的市场标识,如:

youmeng

gfan

.......

此文件里自行根据需求添加渠道名称.

然后看一下实现批量打包AntTest类中的内容:

注意:红色标注部分需要进行修改:

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.text.SimpleDateFormat;
import java.util.Calendar;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));<span style="color:#FF0000;">// 关键代码</span>ProjectHelper.configureProject(project, new File(_buildFile));}public void runTarget(String _target) throws Exception {// Test if the project existsif (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 targetproject.executeTarget(_target);}<span style="color:#FF0000;">private final static String projectBasePath = "D:\\android\\workspace3\\XXX";//要打包的项目根目录private final static String copyApkPath = "D:\\android\\apktest";//保存打包apk的根目录private final static String signApk = "XXX-release.apk";//这里的文件名必须是准确的项目名!private final static String reNameApk = "XXX_";//重命名的项目名称前缀(地图项目不用改)private final static String placeHolder = "@market@";//需要修改manifest文件的地方(占位符)
</span>public static void main(String args[]) {long startTime = 0L;long endTime = 0L;long totalTime = 0L;Calendar date = Calendar.getInstance();SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");try {System.out.println("---------ant批量自动化打包开始----------");startTime = System.currentTimeMillis();date.setTimeInMillis(startTime);System.out.println("开始时间为:" + sdf.format(date.getTime()));BufferedReader br = new BufferedReader(new FileReader("market.txt"));String flag = null;while ((flag = br.readLine()) != null) {// 先修改manifest文件:读取临时文件中的@market@修改为市场标识,然后写入manifest.xml中String tempFilePath = projectBasePath + File.separator+ "AndroidManifest.xml.temp";String filePath = projectBasePath + File.separator+ "AndroidManifest.xml";write(filePath, read(tempFilePath, flag.trim()));// 执行打包命令AntTest mytest = new AntTest();mytest.init(projectBasePath + File.separator + "build.xml",projectBasePath);mytest.runTarget("clean");mytest.runTarget("release");// 打完包后执行重命名加拷贝操作File file = new File(projectBasePath + File.separator + "bin"+ File.separator + signApk);// bin目录下签名的apk文件File renameFile = new File(copyApkPath + File.separator + reNameApk+ flag + ".apk");boolean renametag = file.renameTo(renameFile);System.out.println("rename------>"+renametag);System.out.println("file ------>"+file.getAbsolutePath());System.out.println("rename------>"+renameFile.getAbsolutePath());}System.out.println("---------ant批量自动化打包结束----------");endTime = System.currentTimeMillis();date.setTimeInMillis(endTime);System.out.println("结束时间为:" + sdf.format(date.getTime()));totalTime = endTime - startTime;System.out.println("耗费时间为:" + getBeapartDate(totalTime));} catch (Exception e) {e.printStackTrace();System.out.println("---------ant批量自动化打包中发生异常----------");endTime = System.currentTimeMillis();date.setTimeInMillis(endTime);System.out.println("发生异常时间为:" + sdf.format(date.getTime()));totalTime = endTime - startTime;System.out.println("耗费时间为:" + getBeapartDate(totalTime));}}/*** 根据所秒数,计算相差的时间并以**时**分**秒返回* * @param d1* @param d2* @return*/public static String getBeapartDate(long m) {m = m / 1000;String beapartdate = "";int nDay = (int) m / (24 * 60 * 60);int nHour = (int) (m - nDay * 24 * 60 * 60) / (60 * 60);int nMinute = (int) (m - nDay * 24 * 60 * 60 - nHour * 60 * 60) / 60;int nSecond = (int) m - nDay * 24 * 60 * 60 - nHour * 60 * 60 - nMinute* 60;beapartdate = nDay + "天" + nHour + "小时" + nMinute + "分" + nSecond + "秒";return beapartdate;}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工程中需要进行修改的部分:

1. 修改local.properties中的sdk根目录:

sdk.dir=D:\\android\\android-sdk-windows-r17\\android-sdk-windows-r17

2. 修改ant.properties中签名文件的路径和密码(如果需要)
    key.store=D:\\android\\mykeystore
    key.store.password=123456
    key.alias=mykey
    key.alias.password=123456

3. 修改AndroidManifest.xml.temp
    拷贝AndroidManifest.xml一份,命名为AndroidManifest.xml.temp
    将需要替换的地方改为占位符,需与打包工程AntTest中的placeHolder常量一致

如: <meta-data android:value="@market @" android:name="UMENG_CHANNEL"/>

4. Build.xml中:

<project name="XXX" default="help">,XXX必须为Android工程名称.

如果机器没有配置过Ant环境变量,可根据如下步骤进行配置:

ANT环境变量设置:

Windows下ANT用到的环境变量主要有2个,ANT_HOME 、PATH。

设置ANT_HOME指向ant的安装目录。

设置方法:
ANT_HOME = D:/apache_ant_1.7.0

将%ANT_HOME%/bin; %ANT_HOME%/lib添加到环境变量的path中。

设置方法:
PATH = %ANT_HOME%/bin; %ANT_HOME%/lib

转载于:https://my.oschina.net/fanxiao/blog/92253

使用Ant 实现批量打包Android应用相关推荐

  1. ant 实现批量打包android应用

    很多的应用中需要加上应用推广的统计,如果一个一个的去生成不同渠道包的应用,效率低不说,还有可能不小心弄错了分发渠道,使用ant可以批量生成应用. 一.添加渠道包信息 为了统计渠道信息,就不得不在程序的 ...

  2. android打包工具多渠道批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案...

    今天写一篇文章来总结下android批量打渠道包美团版本.之前项目上一直用的是gradle 批量打包方式,那个速度啊真是令人发指,15个渠道得跑上半个小时,出去吃顿饭回来,还在跑.特别是赶上项目上线的 ...

  3. android 美团批量打包,Android 快速渠道批量打包详解教程-美团多渠道打包方案

    今天写一篇文章来总结下android批量打渠道包美团版本.之前项目上一直用的是gradle 批量打包方式,那个速度啊真是令人发指,15个渠道得跑上半个小时,出去吃顿饭回来,还在跑.特别是赶上项目上线的 ...

  4. Ant自动批量打包多渠道APK

    一.准备工作 1. 下载安装Ant     http://ant.apache.org/bindownload.cgi(官网下载)     下载完成后解压到指定目录并将bin目录配置到环境变量Path ...

  5. android shell 批量打包,Android执行shell命令打包

    Android执行shell命令封装 Android可直接调用Runtime执行shell命令来实现一些功能,在此进行了一个封装. 将需要执行的命令添加到一个数组,并判断是否已root,还有一个回调接 ...

  6. android打包工具多渠道批量打包,android 二次打包完成apk多渠道打包的方法

    本文介绍将渠道号写入assets文件里面,通过解压apk修改assets里的文件,用Java代码生成jarsigner脚本并运行脚本二次打包的方式来获取新的渠道包 此打包方式一个渠道包只需要5秒左右, ...

  7. 安卓快速实现多渠道打包(3步傻瓜式批量打包)

    安卓应用上传市场是个体力活, 如果集成各类统计,单单就是打包的工作量就很可观,虽然可以使用Ant命令批量打包,但是Ant配置使用相当繁琐,初学者很难掌握,今天就教给大家一个只需要三步就可以完成批量傻瓜 ...

  8. android ant批量打包

    当我们对安卓项目需要分很多渠道打包的时候,批量打包工具无疑是个不二选择,批量打包的方式大概可以分为两种,第一是通过第三方的打包平台,比如360加固宝,这确实是个很好的工具,既提高了源代码的安全性能,又 ...

  9. Android 使用 Ant 批量打包

    1.先下载安装 Ant,下载地址:http://ant.apache.org/ 点击打开链接: 下载完成后,安装: 1)解压Ant,比如解压到D:\download\Ant 2) 我的电脑 -> ...

最新文章

  1. 为什么JS是单线程?JS中的Event Loop(事件循环)?JS如何实现异步?setimeout?
  2. mina 中的IoBufer(一)
  3. Docker: Failed to get D-Bus connection: No connection to service
  4. lnmp1.4上thinkphp5.0出现404的解决办法
  5. libevent源码学习-----阅读心得
  6. c++不好可以学qt吗_普通人可以学Python吗
  7. [和管子对话] 2 2007-4-6/抽象类和接口的谁是谁非
  8. Vue 使用 Echarts 显示热力地图信息
  9. android常用的动态分析工具,Android逆向-4.IDA工具介绍-动态分析界面简单介绍-Go语言中文社区...
  10. 削峰填谷 matlab,风电与电动汽车协同并网调度环境模型
  11. ceph的rbd使用和理解(全)
  12. 移动端手指滑动的距离
  13. 第十三届——蓝桥杯嵌入式第二场
  14. UE4带Alpha通道透明效果贴图的相关问题
  15. 【Excel常用函数】VLookup函数使用教程,附视频教程
  16. Linux命令学习笔记(一)目录操作
  17. 大众点评:开放质疑与阿里竞争
  18. Android加载超长图(微博长图)
  19. 提示由于找不到MSVCR120.dll文件,怎么修复呢?MSVCR120.dll是什么文件?
  20. pandas进阶用法(一)筛选条件、多重索引、缺失值

热门文章

  1. Visual studio 2012 创建web service
  2. [过年菜谱之]红烧鸡
  3. Spring Cloud 中的@FeignClient注解
  4. SpringBoot项目在启动时出现了Cannot determine embedded database driver class for database type NONE 错误
  5. 根据数字生成唯一数字_PLSQL——根据上下数字生成等差数列补充空白行
  6. kkFileView ---- 文件预览开源项目
  7. java 下载管理_Java多线程文件下载管理器详解
  8. visual studio 自带的 宏 没反应_横山宏科幻动漫模型:插图造型怪异的胡佛战车欣赏...
  9. win7 32位系统安装postmant无法正常启动。启动显示黑屏界面
  10. oracle复制表结构与表数据