1. 程式人生 > >Android採用Ant批量打包

Android採用Ant批量打包

Ant批量打包的目的是:Android應用市場繁雜,有時候可能需要統計你的app在各個渠道的下載量等資訊,而統計各個渠道時是要做區分的,你需要在專案的配置檔案中新增資料元,來標示我們的應用是在哪個渠道上釋出的。

1、準備工作:

在正式開始Ant打包前,需要下載和配置Ant環境,下載地址:ant下載 


下載後解壓安裝包,解壓後的目錄如下:


接下來就是配置Ant的環境變數:

建立ANT_HOME變數,填入路徑:E:\apache-ant-1.9.7-bin\apache-ant-1.9.7


然後在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 update project --path命令時,可能會出現下邊的錯誤:


  原因是需要配置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= "@[email protected]" android:name="UMENG_CHANNEL"/>  在之後的程式碼中,我們會將@[email protected]替換成我們的渠道名稱

(3)、建立好之後,我們在建立一個名為  ant.properties 的檔案,在裡邊新增你的簽名檔案資訊,如圖所示:

 分別是keystore儲存路徑,密碼,別名,別名密碼

 

key.store=E:\\glodon.keystore
key.store.password=123456
key.alias=glodon.keystore
key.alias.password=123456
注意把build.xml下的name替換成當前專案的名稱:

好,到目前為止,專案需要配置的資訊配置的差不多了。

此時專案目錄結構為:(紅框為新增部分)


(3)、建立自動打包程式

   新建一個java專案,我的專案名稱為:AntTest

專案結構如下:


其中,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 = "@[email protected]";// 需要修改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檔案:讀取臨時檔案中的@[email protected]修改為市場標識,然後寫入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。

正確打包成功後,如圖:


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

注意:如果專案關聯的有第三方jar包,需要給依賴jar包匯入build.xml和local.properties,記得把build.xml的name修改為專案的名稱。否則,打包會失敗的。。。。

相關推薦

Android採用Ant批量打包

Ant批量打包的目的是:Android應用市場繁雜,有時候可能需要統計你的app在各個渠道的下載量等資訊,而統計各個渠道時是要做區分的,你需要在專案的配置檔案中新增資料元,來標示我們的應用是在哪個渠道上釋出的。 1、準備工作: 在正式開始Ant打包前,需要下載和配置Ant環

使用Ant批量打包Android專案

參考:http://blog.sina.com.cn/s/blog_74c22b21010173f8.html 補充遇到的問題:沒有先clean專案就去ant打包,在proguard.cfg或者proguard-project.txt檔案中引入了找不到的jar包導致can

android Ant 批量多渠道打包 總結!

最近研究android裡用ant打多個渠道的apk包,終於搞出頭緒!!走了很多錯路,希望大家不要這樣子!!下面就是個人的幾點總結,希望對大家有幫助:      首先說的是我用的ant不是eclipse和android SDk裡面自帶的ant,而是從這裡下載的 -- Ant

android Ant 批量多渠道打包

一直以來都是手動打包android程式,真可謂苦不堪言啊,以前試過用ant打包,但是失敗了,最近剛到新公司,又開始研究ant這玩意了,查閱了網上一些文章,結合自己的情況,硬是要弄出來才行,這裡就作下記錄吧。 1,準備 ant打包自然需要ant,可以去http://an

Mac中用Ant實現Android批量打包碰到的一些問題以及解決方法

Hello!各位新年好! 昨天下午開始上班,開始整理以前的筆記,留個印記,以免遺忘,當然若能對別人有幫助也再好不過了,今日深圳天氣好的不像話,陽光透過玻璃灑在臉上,舒爽! 首先打包需要準備的情況: 1,Ant和JDK得安裝好了,Ant去官網

android ant 自動批量打包——帶有第三方專案library的情況

如果你每次打包都需要不斷地手動打包,通過不斷地複製貼上,當你打幾百個包的情況下,我相信你一定會瘋掉的,當然,這種事情在我們程式設計師看來,都是可以解決的事情,因為,我們的工作就是讓本來繁瑣的工作變得簡單一點。今天我們就需要簡單地介紹一下ant批量打包的問題吧。 網上看到的資

Android多渠道批量打包

文件 boolean clas 跟蹤 技術 ref bst 更新 xiaomi 如若感覺排版不舒服,請移步Android多渠道批量打包 1、為什麽要進行多渠道打包?   安卓應用商店(一個商店也叫做一個渠道,如豌豆莢,360手機助手,應用寶)眾多

Android中使用Ant編譯打包

C:\Users\hubin5\Desktop\temp\0503>android create project -k com.android.Tank-a Tank-t 4-p G:\projects\tankError:Project folder 'G:\projects\tank'isnot e

Android ANT 多渠道打包解決方案

<span style="font-size:18px;"><!--Android 分渠道打包步驟--> <!--打包之前請確定--> ANDROID_HOME 環境變數 即ANDROID_SDK的安裝路徑 如:

Android自動化構建之Ant多渠道打包實踐(下)

前言 上一篇(Android自動化構建之Ant多渠道打包實踐(上))已經介紹了Android的apk是如何構建的,本篇部落格繼續Ant打包的實踐過程。 整合友盟統計SDK 這裡以友盟統計為例,對各個渠道進行統計,我們需要先整合它的SDK 配置許可權

Android Ant 多渠道打包

[mw_shl_code=java,true]<project     name="TestMutilChannelApk"     default="release" >     <!-- ANT環境變數 -->     <property environment="env"

android SDK Tools跟新後不能用ant進行打包問題,Could not load definitions from resource anttasks.properties. It co

2017年05月份,發現我跟新android SDK Tools 為最新版後不能進行ant打包了,之前都是可以的,打包的時候報的錯誤是: [taskdef] Could not load definitions from resource anttasks.p

Ant_android Ant 批量多渠道打包(2)

最近研究android裡用ant打多個渠道的apk包,終於搞出頭緒!!走了很多錯路,希望大家不要這樣子!!下面就是個人的幾點總結,希望對大家有幫助:      首先說的是我用的ant不是eclipse和android SDk裡面自帶的ant,而是從這裡下載的

android 使用ant打包或者生成jar

一、生成build.xml檔案 Eclipse 中使用Ant為Android打包並且簽名 Android Sdk中自帶檔案,在{sdkpath}tools/ant目錄下的3個檔案 其中build.xml和unbuild.xml中定義了大量基礎構建方法和構建策略。我們只需要

[Gradle] Android Studio批量打包完全自定義APK包名

Gradle 本身是基於 Groovy 語法, 支援批量打包, 非常方便, 大家都知道的.  但在批量打包時, 肯定有個包名重新命名的需求, 比如當前專案的 versionName 是 1.2.0, 使用者在裝置安裝APK後所看到的版本號就是 v1.2.0. 當然, APK

Android幾種常見的多渠道(批量)打包方式介紹

2018.05.18編輯,由於谷歌對v2簽名方式的要求,所以現在用新一代打包方式比較方便:-------------------------------------------------------------------------------------------多渠

Android批量打包提速

黎明前的黑暗 使用Ant或者Gradle來給程式進行多渠道批量打包,通常都是在manifest檔案中寫入一個meta標籤: <meta-data android:name="CHANNEL" android:value="xxx" /> me

Android自動化構建之Ant多渠道打包實踐(上)

前言 Ant是歷史比較悠久的一個自動化構建工具,Android開發者可以通過它來實現自動化構建,也可以實現多渠道打包,關於apk打包的方式一般有Ant、Python、Gradle三種,這三種打包方式都各自有優點和缺點,本篇博文先給大家介紹如何使用Ant來實現自

Android studio 自己定義打包APK名稱

nts 名稱 code apk conf androi 版本 ant each Android Studio打包應用默認生成的apk名稱是:app-release.apk 、假設我們要讓生成的apk名跟我們版本號包名有聯系的話。那我們就要自己定義生成的apk名了,要

B/S模式實現批量打包apk

fad tle tdi inpu 控制臺輸出 dir static ams fine 界面流程 界面例如以下: 這是一個使用html編寫的界面,界面分為兩半。兩個frame。左邊為操作欄,右邊為控制臺輸出。 打包流程: 選擇須要打包的渠道後,