主要講下如何自動構建工具Ant, 對應用進行批量打包, 產生對應不同市場的應用:
首先分別看一下用於打包的Java工程AntTest和需要被打包進行發布的Android工程結構: market.txt裡儲存需要打包的市場標識,如:youmenggfan.......此檔案裡自行根據需求添加渠道名稱. 然後看一下實現批量打包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:androidworkspace3XXX";//要打包的項目根目錄private final static String copyApkPath = "D:androidapktest";//儲存打包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:androidandroid-sdk-windows-r17android-sdk-windows-r17
2. 修改ant.properties中籤名檔案的路徑和密碼(如果需要)
key.store=D:androidmykeystore
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