Android采用Ant批量打包

Ant批量打包的目的是:Android应用市场繁杂,有时候可能需要统计你的app在各个渠道的下载量等信息,而统计各个渠道时是要做区分的,你需要在项目的配置文件中添加数据元,来标示我们的应用是在哪个渠道上发布的。

1、准备工作:

在正式开始Ant打包前,需要下载和配置Ant环境,下载地址:ant下载 


下载后解压安装包,解压后的目录如下:

Android采用Ant批量打包_第1张图片

接下来就是配置Ant的环境变量:

创建ANT_HOME变量,填入路径:E:\apache-ant-1.9.7-bin\apache-ant-1.9.7

Android采用Ant批量打包_第2张图片

然后在Path中添加 %ANT_HOME%/bin;%ANT_HOME%/lib;

Ok,到这里,Ant环境变量算是配置完毕。

然后打开cmd命令行输入ant命令,看是不是出现下图的提示,是的话,就说明配置成功了。


2、开始Ant打包

(1)、新建一个项目,这里我的项目名称是:AntPackage,纯粹的一个空项目,啥也没呢。

 然后就是使用android自带的命令创建我们的build.xml文件,在cmd命令行使用 cd /d path 的命令,到达我们工程的根目录,然后使用 android update project --path . 命令,在当前目录下面创建我们的build.xml文件。如下图:

Android采用Ant批量打包_第3张图片

   注意:在输入android update project --path命令时,可能会出现下边的错误:

Android采用Ant批量打包_第4张图片

  原因是需要配置ANDROID_HOME环境变量,ANDROID_HOME:F:\adt-bundle-windows-x86_64-20140321\adt-bundle-windows-x86_64-20140321\sdk,然后在path下添加%ANDROID_HOME%/tools;

(2)、创建完build.xml文件之后,我们首先在AndroidManifest.xml文件中,添加一个数据元,代码如下:


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

后面的name属性根据不同的平台各有差异,我们要做的,就是替代前面的value,并实现打包

修改好之后,我们复制清单文件,然后改名为 AndroidManifest.xml.temp ,之后修改AndroidManifest.xml.temp文件内容,将数据源换成我们的替换符,如下所示

<meta-data android:value= "@market@" android:name="UMENG_CHANNEL"/>  在之后的代码中,我们会将@market@替换成我们的渠道名称

(3)、创建好之后,我们在创建一个名为  ant.properties 的文件,在里边添加你的签名文件信息,如图所示:

 分别是keystore保存路径,密码,别名,别名密码

 

key.store=E:\\glodon.keystore
key.store.password=123456
key.alias=glodon.keystore
key.alias.password=123456
注意把build.xml下的name替换成当前项目的名称:
Android采用Ant批量打包_第5张图片

好,到目前为止,项目需要配置的信息配置的差不多了。

此时项目目录结构为:(红框为新增部分)

Android采用Ant批量打包_第6张图片

(3)、创建自动打包程序

   新建一个java项目,我的项目名称为:AntTest

项目结构如下:

Android采用Ant批量打包_第7张图片

其中,market.txt填写的是发布到各个应用市场的名称,如图:


lib下的两个jar包,可以在Ant解压目录的lib下找到,复制过来就行,复制后记得右键Build path。

接下来就是主要代码类,AntTest.java,代码如下:

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;

/**
 * Ant自动打包程序
 * @author liyx-k
 *
 */
public class AntTest {
  private Project project;

  private final static String projectBasePath = "F:\\GlodonProject\\AntPackage";// 要打包的项目根目录
  private final static String copyApkPath = "E:\\MutilPackage";// 保存打包之后的apk的根目录
  private final static String signApk = "AntPackage-release.apk";// 这里的文件名必须是准确的项目名!就是Project工程的bin目录下面的apk安装包的名字
  private final static String reNameApk = "AntPackage_";// 重命名之后的项目名称前缀(地图项目不用改)
  private final static String placeHolder = "@market@";// 需要修改manifest文件的地方(占位符)

  @SuppressWarnings("resource")
  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");
        // 将打包好的apk重命名后移动到copyApkPath位置
        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));
    }
  }

  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);
    if (_baseDir == null)
      _baseDir = new String(".");
    project.setBasedir(_baseDir);
    if (_buildFile == null)
      _buildFile = new String(projectBasePath + File.separator
          + "build.xml");
    ProjectHelper.configureProject(project, new File(_buildFile));
  }

  public void runTarget(String _target) throws Exception {
    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 (_target == null)
      _target = project.getDefaultTarget();
    project.executeTarget(_target);
  }

  /**
   * 根据所秒数,计算相差的时间并以**时**分**秒返回
   * 
   * @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;
        }
      }
    }
  }
}

其中,需要修改的地方有:


第一个是需要打包项目的根目录,第二个是生成APK的目录,第三个是生成apk的名称,一定注意- ,第四个是项目名称前缀,到这里配置应该差不多了,接下来运行看看。

三、运行AntTest项目,进行批量打包;

运行后发现下边的错误:


解决方案:

Eclipse菜单 – Window – Preferences – Java – Installed JREs – 选中栏目表格中的jre项 – Edit – Add External JARs –  选择jdk目录/lib/tools.jar  -  确认其加入JRE system libraries – Finish – OK。

正确打包成功后,如图:

Android采用Ant批量打包_第8张图片

Ok这就打包成功了。。。。。。。。。。。。。。。。。

注意:如果项目关联的有第三方jar包,需要给依赖jar包导入build.xml和local.properties,记得把build.xml的name修改为项目的名称。否则,打包会失败的。。。。



你可能感兴趣的:(ant,渠道打包,Ant批量打包)