通過ant指令碼編譯打包android工程

yangxi_001發表於2014-03-14

通過ant指令碼,編譯打包android工程


1.Android程式編譯、打包、簽名、釋出的三種方式: 
方式一:命令列手動編譯打包 
方式二:使用ant自動編譯打包 
方式三:使用eclipse+ADT編譯打包 

2.Android編譯、打包的步驟: 
2.1第一步 生成R.java類檔案: 
Eclipse中會自動生成R.java,ant和命令列使用android SDK提供的aapt.ext程式生成R.java。 

2.2第二步 將.aidl檔案生成.java類檔案: 
Eclipse中自動生成,ant和命令列使用android SDK提供的aidl.exe生成.java檔案。 

2.3第三步 編譯.java類檔案生成class檔案: 
Eclipse中自動生成,ant和命令列使用jdk的javac編譯java類檔案生成class檔案。 

2.4第四步 將class檔案打包生成classes.dex檔案: 
Eclipse中自動生成,ant和命令列使用android SDK提供的dx.bat命令列指令碼生成classes.dex檔案。 

2.5第五步 打包資原始檔(包括res、assets、androidmanifest.xml等): 
Eclipse中自動生成,ant和命令列使用Android SDK提供的aapt.exe生成資源包檔案。 

2.6第六步 生成未簽名的apk安裝檔案: 
Eclipse中自動生成debug簽名檔案存放在bin目錄中,ant和命令列使用android SDK提供的apkbuilder.bat命令指令碼生成未簽名的apk安裝檔案。 

2.7第七步 對未簽名的apk進行簽名生成簽名後的android檔案: 

Eclipse中使用Android Tools進行簽名,ant和命令列使用jdk的jarsigner對未簽名的包進行apk簽名。 

這個ant指令碼只能編譯打包一個單獨的android工程或依賴一個library 的android工程

首先配置ant的環境變數,這個我就不多少了,自己查。

ant指令碼,生成build.xml

[plain] view plaincopy
  1. <span style="font-size:18px">H:\install\eclipse-SDK-3.7.2-win32\eclipse\android_sdk\tools\android.bat update project -n BuiltDemo -t android-8 -p H:\workspace\prac_a3\BuiltDemo</span>  
在local.properties檔案裡要配置環境變數:
[plain] view plaincopy
  1. <span style="font-size:18px">sdk.dir=H:/install/eclipse-SDK-3.7.2-win32/eclipse/android_sdk  
  2. ANDROID_HOME=H:/install/eclipse-SDK-3.7.2-win32/eclipse/android_sdk  
  3. ANT_HOME=F:/Soft/ant/apache-ant-1.9.2  
  4. JAVA_HOME=C:/Program Files/Java/jdk1.6.0_10</span>  
執行編譯,根據build.xml檔案裡的設定區執行debug或者release:
[plain] view plaincopy
  1. <span style="font-size:18px">H:\install\eclipse-SDK-3.7.2-win32\eclipse\android_sdk\tools\android.bat  debug  
  2. H:\install\eclipse-SDK-3.7.2-win32\eclipse\android_sdk\tools\android.bat release</span>  
以下是我使用的ant指令碼(build.xml),解釋什麼的都有,只能編譯打包一個單獨的android工程或依賴一個library 的android工程:
[html] view plaincopy
  1. <span style="font-size:18px"><?xml version="1.0" encoding="UTF-8"?>  
  2. <project name="BuiltDemo" default="release">  
  3.     <property file="local.properties" />  
  4.   
  5.     <!-- ANT環境變數 -->  
  6.     <property environment="env" />  
  7.     <!-- 應用名稱 -->  
  8.   
  9.     <property name="appName" value="BuiltDemo" />  
  10.     <property name="basedir" value="H:/workspace/prac_a3/BuiltDemo" />  
  11.     <property name="library-dir" value="H:/workspace/prac_a3/BuiltDemo">  
  12.     </property>  
  13.     <!-- SDK目錄(獲取作業系統環境變數ANDROID_SDK_HOME的值) -->  
  14.     <!-- <property name="sdk-folder" value="${env.ANDROID_SDK_HOME}" /> -->  
  15.     <property name="sdk-folder" value="${env.ANDROID_HOME}" />  
  16.     <!-- SDK指定平臺目錄 -->  
  17.     <property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-8" />  
  18.     <!-- SDK中tools目錄 -->  
  19.     <property name="sdk-tools" value="${sdk-folder}/tools" />  
  20.     <!-- SDK指定平臺中tools目錄 -->  
  21.     <property name="sdk-platform-tools" value="${sdk-folder}/platform-tools" />  
  22.   
  23.     <!-- 使用到的命令(當前系統為windows,如果系統為linux,可將.bat檔案替換成相對應的命令) -->  
  24.     <property name="aapt" value="${sdk-platform-tools}/aapt.exe" />  
  25.     <property name="aidl" value="${sdk-platform-tools}/aidl.exe" />  
  26.     <property name="dx" value="${sdk-platform-tools}/dx.bat" />  
  27.     <property name="apkbuilder" value="${sdk-tools}/apkbuilder.bat" />  
  28.     <property name="jarsigner" value="${env.JAVA_HOME}/bin/jarsigner" />  
  29.   
  30.     <!-- 編譯需要的jar; 如果專案使用到地圖服務則需要maps.jar -->  
  31.     <property name="android-jar" value="${sdk-platform-folder}/android.jar" />  
  32.   
  33.     <!-- 編譯aidl檔案所需的預處理框架檔案framework.aidl -->  
  34.     <property name="framework-aidl" value="${sdk-platform-folder}/framework.aidl" />  
  35.   
  36.     <!-- 生成R檔案的相對目錄 -->  
  37.     <property name="outdir-gen" value="gen" />  
  38.     <!-- 編譯後的檔案放置目錄 -->  
  39.     <property name="outdir-bin" value="out" />  
  40.   
  41.     <!-- 清單檔案 -->  
  42.     <property name="manifest-xml" value="AndroidManifest.xml" />  
  43.     <!-- 原始檔目錄 -->  
  44.     <property name="resource-dir" value="res" />  
  45.     <property name="asset-dir" value="assets" />  
  46.     <!-- java原始檔目錄 -->  
  47.     <property name="srcdir" value="src" />  
  48.     <property name="srcdir-ospath" value="${basedir}/${srcdir}" />  
  49.     <!-- 外部類庫所在目錄 -->  
  50.     <property name="external-lib" value="libs" />  
  51.     <property name="external-lib-ospath" value="${basedir}/${external-lib}" />  
  52.   
  53.     <!-- 生成class目錄 -->  
  54.     <property name="outdir-classes" value="${outdir-bin}" />  
  55.     <property name="outdir-classes-ospath" value="${basedir}/${outdir-classes}" />  
  56.   
  57.     <!-- classes.dex相關變數 -->  
  58.     <property name="dex-file" value="classes.dex" />  
  59.     <property name="dex-path" value="${outdir-bin}/${dex-file}" />  
  60.     <property name="dex-ospath" value="${basedir}/${dex-path}" />  
  61.   
  62.     <!-- 經過aapt生成的資源包檔案 -->  
  63.     <property name="resources-package" value="${outdir-bin}/resources.ap_" />  
  64.     <property name="resources-package-ospath" value="${basedir}/${resources-package}" />  
  65.   
  66.     <!-- 未認證apk包 -->  
  67.     <property name="out-unsigned-package" value="${outdir-bin}/${appName}-unsigned.apk" />  
  68.     <property name="out-unsigned-package-ospath" value="${basedir}/${out-unsigned-package}" />  
  69.   
  70.     <!-- 證照檔案 -->  
  71.     <property name="keystore-file" value="${basedir}/sbx" />  
  72.   
  73.     <!-- 已認證apk包 -->  
  74.     <property name="out-signed-package" value="${outdir-bin}/${appName}.apk" />  
  75.     <property name="out-signed-package-ospath" value="${basedir}/${out-signed-package}" />  
  76.   
  77.   
  78.     <!-- 初始化工作 -->  
  79.     <target name="init">  
  80.         <echo>Initializing all output directories...</echo>  
  81.         <delete dir="${outdir-bin}" />  
  82.         <mkdir dir="${outdir-bin}" />  
  83.         <mkdir dir="${outdir-classes}" />  
  84.     </target>  
  85.   
  86.     <!-- 根據工程中的資原始檔生成R.java檔案 -->  
  87.     <target name="gen-R" depends="init">  
  88.         <echo>Generating R.java from the resources...</echo>  
  89.         <!--<exec executable="${aapt}" failonerror="true">  
  90.             <arg value="package" />  
  91.             <arg value="-f" />  
  92.             <arg value="-m" />  
  93.             <arg value="-J" />  
  94.             <arg value="${outdir-gen}" />  
  95.             <arg value="-S" />  
  96.             <arg value="${resource-dir}" />  
  97.             <arg value="-M" />  
  98.             <arg value="${manifest-xml}" />  
  99.             <arg value="-I" />  
  100.             <arg value="${android-jar}" />  
  101.         </exec>-->  
  102.   
  103.   
  104.         <exec executable="${aapt}" failonerror="true">  
  105.             <arg value="package" />  
  106.             <arg value="-m" />  
  107.             <arg value="--auto-add-overlay" />  
  108.             <arg value="-J" />  
  109.             <arg value="${outdir-gen}" />  
  110.             <arg value="-M" />  
  111.             <arg value="${manifest-xml}" />  
  112.             <arg value="-S" />  
  113.             <arg value="${resource-dir}" />  
  114.             <arg value="-S" />  
  115.             <arg value="${library-dir}/${resource-dir}" />  
  116.             <arg value="--extra-packages" />  
  117.             <arg value="com.mobcent.share.android" />  
  118.             <arg value="-A" />  
  119.             <arg value="${asset-dir}" />  
  120.             <arg value="-I" />  
  121.             <arg value="${android-jar}" />  
  122.         </exec>  
  123.     </target>  
  124.   
  125.   
  126.     <!-- 編譯aidl檔案 -->  
  127.     <target name="aidl" depends="gen-R">  
  128.         <echo>Compiling .aidl into java files...</echo>  
  129.         <apply executable="${aidl}" failonerror="true">  
  130.             <!-- 指定預處理檔案 -->  
  131.             <arg value="-p${framework-aidl}" />  
  132.             <!-- aidl宣告的目錄 -->  
  133.             <arg value="-I${srcdir}" />  
  134.             <!-- 目標檔案目錄 -->  
  135.             <arg value="-o${outdir-gen}" />  
  136.             <!-- 指定哪些檔案需要編譯 -->  
  137.             <fileset dir="${srcdir}">  
  138.                 <include name="**/*.aidl" />  
  139.             </fileset>  
  140.         </apply>  
  141.     </target>  
  142.   
  143.     <!-- 將工程中的java原始檔編譯成class檔案 -->  
  144.     <target name="compile" depends="aidl">  
  145.         <echo>Compiling java source code...</echo>  
  146.         <javac encoding="utf-8" target="1.6" destdir="${outdir-classes}" bootclasspath="${android-jar}">  
  147.             <src path="src" />  
  148.             <src path="gen" />  
  149.             <src path="${library-dir}/src" />  
  150.             <classpath>  
  151.                 <fileset dir="${external-lib}" includes="*.jar" />  
  152.                 <fileset dir="${library-dir}/libs" includes="*.jar" />  
  153.                 <filelist>  
  154.                     <file name="${android-maps-jar}" />  
  155.                 </filelist>  
  156.             </classpath>  
  157.         </javac>  
  158.     </target>  
  159.   
  160.     <!-- 將.class檔案轉化成.dex檔案 -->  
  161.     <target name="dex" depends="compile">  
  162.         <echo>Converting compiled files and external libraries into a .dex  
  163.             file...  
  164.         </echo>  
  165.         <exec executable="${dx}" failonerror="true">  
  166.             <arg value="--dex" />  
  167.             <!-- 輸出檔案 -->  
  168.             <arg value="--output=${dex-ospath}" />  
  169.             <!-- 要生成.dex檔案的源classes和libraries -->  
  170.             <arg value="${outdir-classes-ospath}" />  
  171.             <arg value="${external-lib-ospath}" />  
  172. <!--             <arg value="${library-dir}/libs" /> -->  
  173.         </exec>  
  174.     </target>  
  175.   
  176.   
  177.     <!-- 將資原始檔放進輸出目錄 -->  
  178.     <!--在這截斷-->  
  179.     <target name="package-res-and-assets" depends="dex">  
  180.         <echo>Packaging resources and assets...</echo>  
  181.         <exec executable="${aapt}" failonerror="true">  
  182.             <arg value="package" />  
  183.             <arg value="-f" />  
  184.             <arg value="-M" />  
  185.             <arg value="${manifest-xml}" />  
  186.             <arg value="-S" />  
  187.             <arg value="${resource-dir}" />  
  188.   
  189.             <arg value="-A" />  
  190.             <arg value="${asset-dir}" />  
  191.   
  192.             <arg value="-S" />  
  193.             <arg value="${library-dir}/${resource-dir}" />  
  194.   
  195.             <arg value="-A" />  
  196.             <arg value="${library-dir}/${asset-dir}" />  
  197.   
  198.             <arg value="-I" />  
  199.             <arg value="${android-jar}" />  
  200.             <arg value="-F" />  
  201.             <arg value="${resources-package}" />  
  202.   
  203.             <arg value="--auto-add-overlay" />  
  204.         </exec>  
  205.     </target>  
  206.   
  207.   
  208.     <!-- 打包成未簽證的apk -->  
  209.     <target name="package" depends="dex, package-res-and-assets">  
  210.         <echo>Packaging unsigned apk for release...</echo>  
  211.         <exec executable="${apkbuilder}" failonerror="true">  
  212.             <arg value="${out-unsigned-package-ospath}" />  
  213.             <arg value="-u" />  
  214.               
  215.             <arg value="-z" />  
  216.             <arg value="${resources-package-ospath}" />  
  217.             <arg value="-f" />  
  218.             <arg value="${dex-ospath}" />  
  219.             <arg value="-rf" />  
  220.             <arg value="${srcdir-ospath}" />  
  221.             <arg value="-nf"/>  
  222.             <arg value="${library-dir}/libs"/>  
  223.         </exec>  
  224.         <echo>It will need to be signed with jarsigner before being published.  
  225.         </echo>  
  226.     </target>  
  227.   
  228.   
  229.     <!-- 對apk進行簽證 -->  
  230.     <target name="jarsigner" depends="package">  
  231.         <echo>Packaging signed apk for release...</echo>  
  232.         <exec executable="${jarsigner}" failonerror="true">  
  233.             <arg value="-keystore" />  
  234.             <arg value="${keystore-file}" />  
  235.             <arg value="-storepass" />  
  236.             <arg value="111111" />  
  237.             <arg value="-keypass" />  
  238.             <arg value="111111" />  
  239.             <arg value="-signedjar" />  
  240.             <arg value="${out-signed-package-ospath}" />  
  241.             <arg value="${out-unsigned-package-ospath}" />  
  242.             <!-- 不要忘了證照的別名 -->  
  243.             <arg value="sbx" />  
  244.         </exec>  
  245.     </target>  
  246.   
  247.     <!-- 釋出 -->  
  248.     <target name="release" depends="jarsigner">  
  249.         <!-- 刪除未簽證apk -->  
  250.         <delete file="${out-unsigned-package-ospath}" />  
  251.         <echo>APK is released. path:${out-signed-package-ospath}</echo>  
  252.     </target>  
  253.   
  254. </project>  
  255. </span>  

Android官方提供的打包指令碼: 1400多行,我加了中文註釋,希望能看懂。

詳見build.xml

[html] view plaincopy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project name="pet_dog_base_forum" default="release">  
  3.     <!--自己需要新增的屬性 -->  
  4.     <property name="sdk.dir" value="C:/Program Files/android-sdk_r15-windows/android-sdk-windows" />  
  5.     <!--匯入project.properties 檔案,設定了編譯的target 和相關的library工程-->  
  6.     <property file="project.properties" />  
  7.     <!--匯入build.properties檔案,設定了android的目錄和key-->  
  8.     <property file="ant.properties" />  
  9.     <!--  
  10.         This build file is imported by the project build file. It contains  
  11.         all the targets and tasks necessary to build Android projects, be they  
  12.         regular projects, library projects, or test projects.  
  13.   
  14.         At the beginning of the file is a list of properties that can be overridden  
  15.         by adding them to your build.properties (properties are immutable, so their  
  16.         first definition sticks and is never changed).  
  17.   
  18.         Follows:   
  19.         - custom task definitions,  
  20.         - more properties (do not override those unless the whole build system is modified).  
  21.         - macros used throughout the build,  
  22.         - base build targets,  
  23.         - debug-specific build targets,  
  24.         - release-specific build targets,  
  25.         - instrument-specific build targets,  
  26.         - test project-specific build targets,  
  27.         - install targets,  
  28.         - help target  
  29.           
  30.                        步驟如下:  
  31.         —— 自定義task  
  32.         —— 設定相關屬性  
  33.         —— 全域性的使用整個構建  
  34.         —— 基本bulid的targets    
  35.         —— debug使用的targets  
  36.         —— release使用的targets         
  37.         —— 特定儀器使用的targets  
  38.         —— 測試使用的targets  
  39.         —— 安裝的targets  
  40.         —— 幫助的targets                
  41.     -->  
  42.   
  43.     <!-- ********** Overrideable Properties ********** -->  
  44.     <!-- ********** 可重寫的屬性 ********** -->  
  45.   
  46.     <!-- You can override these values in your build.xml or build.properties.  
  47.          Overriding any other properties may result in broken build. -->  
  48.     <!-- 你可以覆蓋build.xml 或者 build.properties 檔案中的任何屬性,覆蓋任何一個屬性,都可能導致build出錯,慎用 -->  
  49.   
  50.     <!-- Tells adb which device to target. You can change this from the command line  
  51.          by invoking "ant -Dadb.device.arg=-d" for device "ant -Dadb.device.arg=-e" for  
  52.          the emulator. -->  
  53.     <!-- 設定連結的機器,  
  54.     ant -Dadb.device.arg=-d 使用連結當前的裝置  
  55.     ant -Dadb.device.arg=-e 使用模擬器  
  56.     -->  
  57.   
  58.     <property name="adb.device.arg" value="" />  
  59.   
  60.   
  61.     <!-- fileset exclude patterns (space separated) to prevent  
  62.          files inside src/ from being packaged. -->  
  63.     <!-- 設定改屬性可以排除編譯一部分程式碼 
  64.     -->  
  65.     <property name="android.package.excludes" value="" />  
  66.   
  67.     <!-- set some properties used for filtering/override. If those weren't defined  
  68.          before, then this will create them with empty values, which are then ignored  
  69.          by the custom tasks receiving them. -->  
  70.     <!-- 
  71.     version.code,version.name可以替換AndroidManifest.xml中的android:versionCode和android:versionName 
  72.     -->  
  73.     <property name="version.code" value="11" />  
  74.     <property name="version.name" value="111" />  
  75.     <property name="aapt.resource.filter" value="" />  
  76.   
  77.     <!-- compilation options -->  
  78.     <property name="java.encoding" value="UTF-8" />  
  79.     <property name="java.target" value="1.6" />  
  80.     <property name="java.source" value="1.6" />  
  81.   
  82.     <!-- Verbosity -->  
  83.     <property name="verbose" value="false" />  
  84.   
  85.     <!-- ********** Custom Tasks ********** -->  
  86.     <!-- ********** 自定義Tasks ********** -->  
  87.       
  88.     <!-- 匯入自定義Task是需要的檔案 -->  
  89.     <path id="android.antlibs">  
  90.         <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />  
  91.     </path>  
  92.   
  93.     <!-- Custom tasks -->  
  94.     <taskdef name="setup" classname="com.android.ant.NewSetupTask" classpathref="android.antlibs" />  
  95.   
  96.     <taskdef name="aapt" classname="com.android.ant.AaptExecTask" classpathref="android.antlibs" />  
  97.   
  98.     <taskdef name="aidl" classname="com.android.ant.AidlExecTask" classpathref="android.antlibs" />  
  99.   
  100.     <taskdef name="renderscript" classname="com.android.ant.RenderScriptTask" classpathref="android.antlibs" />  
  101.   
  102.     <taskdef name="dex" classname="com.android.ant.DexExecTask" classpathref="android.antlibs" />  
  103.   
  104.     <taskdef name="apkbuilder" classname="com.android.ant.ApkBuilderTask" classpathref="android.antlibs" />  
  105.   
  106.     <taskdef name="zipalign" classname="com.android.ant.ZipAlignTask" classpathref="android.antlibs" />  
  107.   
  108.     <taskdef name="xpath" classname="com.android.ant.XPathTask" classpathref="android.antlibs" />  
  109.   
  110.     <taskdef name="if" classname="com.android.ant.IfElseTask" classpathref="android.antlibs" />  
  111.   
  112.     <!-- Emma configuration   
  113.     EMMA 是一種快速的,基於位元組碼指令的Java 程式碼覆蓋工具。  
  114.     -->  
  115.     <property name="emma.dir" value="${sdk.dir}/tools/lib" />  
  116.     <path id="emma.lib">  
  117.         <pathelement location="${emma.dir}/emma.jar" />  
  118.         <pathelement location="${emma.dir}/emma_ant.jar" />  
  119.     </path>  
  120.     <taskdef resource="emma_ant.properties" classpathref="emma.lib" />  
  121.     <!-- End of emma configuration -->  
  122.   
  123.   
  124.     <!-- ********** Other Properties ********** -->  
  125.     <!-- overriding these properties may break the build  
  126.          unless the whole file is updated -->  
  127.   
  128.     <!-- 輸入檔案 -->  
  129.     <property name="source.dir" value="src" />  
  130.     <property name="source.absolute.dir" location="${source.dir}" />  
  131.     <property name="gen.absolute.dir" location="gen" />  
  132.     <property name="resource.absolute.dir" location="res" />  
  133.     <property name="asset.absolute.dir" location="assets" />  
  134.     <property name="jar.libs.dir" value="libs" />  
  135.     <property name="jar.libs.absolute.dir" location="${jar.libs.dir}" />  
  136.     <property name="native.libs.absolute.dir" location="libs" />  
  137.   
  138.     <!-- 輸出檔案 -->  
  139.     <property name="out.dir" value="bin" />  
  140.     <property name="out.absolute.dir" location="${out.dir}" />  
  141.     <property name="out.classes.absolute.dir" location="${out.dir}/classes" />  
  142.     <property name="out.res.absolute.dir" location="${out.dir}/res" />  
  143.   
  144.     <!-- tools location 編譯所需要用到的工具 -->  
  145.     <property name="android.tools.dir" location="${sdk.dir}/tools" />  
  146.     <property name="android.platform.tools.dir" location="${sdk.dir}/platform-tools" />  
  147.     <condition property="exe" value=".exe" else="">  
  148.         <os family="windows" />  
  149.     </condition>  
  150.     <condition property="bat" value=".bat" else="">  
  151.         <os family="windows" />  
  152.     </condition>  
  153.     <property name="adb" location="${android.platform.tools.dir}/adb${exe}" />  
  154.     <property name="zipalign" location="${android.tools.dir}/zipalign${exe}" />  
  155.     <property name="aidl" location="${android.platform.tools.dir}/aidl${exe}" />  
  156.     <property name="aapt" location="${android.platform.tools.dir}/aapt${exe}" />  
  157.     <property name="dx" location="${android.platform.tools.dir}/dx${bat}" />  
  158.     <!-- renderscript location is set by NewSetupTask since we have a choice of  
  159.          several executables based on minSdkVersion -->  
  160.   
  161.     <!-- Intermediate files 中間檔案 -->  
  162.     <property name="dex.file.name" value="classes.dex" />  
  163.     <property name="intermediate.dex.file" location="${out.absolute.dir}/${dex.file.name}" />  
  164.     <property name="resource.package.file.name" value="${ant.project.name}.ap_" />  
  165.   
  166.     <!-- Build property file build的屬性檔案 -->  
  167.     <property name="out.build.prop.file" location="${out.absolute.dir}/build.prop" />  
  168.   
  169.   
  170.     <!-- This is needed by emma as it uses multilevel verbosity instead of simple 'true' or 'false'  
  171.          The property 'verbosity' is not user configurable and depends exclusively on 'verbose'  
  172.          value.  
  173.          這是需要通過艾瑪,因為它使用多級verbosity不是簡單的“true”或“false”。屬性“冗長”不是使用者可配置的,只取決於verbose”值。  
  174.          -->  
  175.     <condition property="verbosity" value="verbose" else="quiet">  
  176.         <istrue value="${verbose}" />  
  177.     </condition>  
  178.   
  179.     <!-- properties for signing in release mode -->  
  180.     <!-- 簽名所需要的檔案 -->  
  181.     <condition property="has.keystore">  
  182.         <and>  
  183.             <isset property="key.store" />  
  184.             <length string="${key.store}" when="greater" length="0" />  
  185.             <isset property="key.alias" />  
  186.         </and>  
  187.     </condition>  
  188.     <condition property="has.password">  
  189.         <and>  
  190.             <isset property="has.keystore" />  
  191.             <isset property="key.store.password" />  
  192.             <isset property="key.alias.password" />  
  193.         </and>  
  194.     </condition>  
  195.   
  196.     <!-- properties for packaging -->  
  197.     <property name="build.packaging.nocrunch" value="true" />  
  198.   
  199.     <!-- ********** Macros ********** -->  
  200.     <!-- ********** 巨集定義         ********** -->  
  201.   
  202.     <!-- macro to do a task on if project.is.library is false.  
  203.          elseText attribute is displayed otherwise -->  
  204.     <!-- 定義了沒有關聯library工程時,將會列印elseText -->  
  205.     <macrodef name="do-only-if-not-library">  
  206.         <attribute name="elseText" />  
  207.         <element name="task-to-do" implicit="yes" />  
  208.         <sequential>  
  209.             <if condition="${project.is.library}">  
  210.                 <else>  
  211.                     <task-to-do />  
  212.                 </else>  
  213.                 <then>  
  214.                     <echo>@{elseText}</echo>  
  215.                 </then>  
  216.             </if>  
  217.         </sequential>  
  218.     </macrodef>  
  219.   
  220.     <!-- macro to do a task on if manifest.hasCode is true.  
  221.          elseText attribute is displayed otherwise -->  
  222.     <macrodef name="do-only-if-manifest-hasCode">  
  223.         <attribute name="elseText" default="" />  
  224.         <element name="task-to-do" implicit="yes" />  
  225.         <sequential>  
  226.             <if condition="${manifest.hasCode}">  
  227.                 <then>  
  228.                     <task-to-do />  
  229.                 </then>  
  230.                 <else>  
  231.                     <if>  
  232.                         <condition>  
  233.                             <length string="@{elseText}" trim="true" when="greater" length="0" />  
  234.                         </condition>  
  235.                         <then>  
  236.                             <echo>@{elseText}</echo>  
  237.                         </then>  
  238.                     </if>  
  239.                 </else>  
  240.             </if>  
  241.         </sequential>  
  242.     </macrodef>  
  243.   
  244.   
  245.     <!-- Configurable macro, which allows to pass as parameters output directory,  
  246.          output dex filename and external libraries to dex (optional)  
  247.          配置巨集,允許通過引數設定輸出的目錄,dex檔案和dex額外的libraries  
  248.           -->  
  249.     <macrodef name="dex-helper">  
  250.         <element name="external-libs" optional="yes" />  
  251.         <attribute name="nolocals" default="false" />  
  252.         <sequential>  
  253.             <!-- sets the primary input for dex. If a pre-dex task sets it to  
  254.                  something else this has no effect -->  
  255.             <property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />  
  256.   
  257.             <!-- set the secondary dx input: the project (and library) jar files  
  258.                  If a pre-dex task sets it to something else this has no effect -->  
  259.             <if>  
  260.                 <condition>  
  261.                     <isreference refid="out.dex.jar.input.ref" />  
  262.                 </condition>  
  263.                 <else>  
  264.                     <path id="out.dex.jar.input.ref">  
  265.                         <path refid="jar.libs.ref" />  
  266.                     </path>  
  267.                 </else>  
  268.             </if>  
  269.   
  270.             <dex executable="${dx}" output="${intermediate.dex.file}" nolocals="@{nolocals}" verbose="${verbose}" previousBuildType="${build.last.target}" buildType="${build.target}">  
  271.                 <path path="${out.dex.input.absolute.dir}" />  
  272.                 <path refid="out.dex.jar.input.ref" />  
  273.                 <external-libs />  
  274.             </dex>  
  275.         </sequential>  
  276.     </macrodef>  
  277.   
  278.     <!-- This is macro that enable passing variable list of external jar files to ApkBuilder  
  279.     設定ApkBuilder 是額外的jar檔案  
  280.     預設把工程下libs中的jar檔案打到APK裡  
  281.          Example of use:  
  282.          <package-helper>  
  283.              <extra-jars>  
  284.                 <jarfolder path="my_jars" />  
  285.                 <jarfile path="foo/bar.jar" />  
  286.                 <jarfolder path="your_jars" />  
  287.              </extra-jars>  
  288.          </package-helper> -->  
  289.     <macrodef name="package-helper">  
  290.         <element name="extra-jars" optional="yes" />  
  291.         <sequential>  
  292.             <apkbuilder outfolder="${out.absolute.dir}" resourcefile="${resource.package.file.name}" apkfilepath="${out.packaged.file}" debugpackaging="${build.is.packaging.debug}" debugsigning="${build.is.signing.debug}" verbose="${verbose}" hascode="${manifest.hasCode}" previousBuildType="${build.last.is.packaging.debug}/${build.last.is.signing.debug}" buildType="${build.is.packaging.debug}/${build.is.signing.debug}">  
  293.                 <dex path="${intermediate.dex.file}" />  
  294.                 <sourcefolder path="${source.absolute.dir}" />  
  295.                 <jarfile refid="jar.libs.ref" />  
  296.                 <nativefolder path="${native.libs.absolute.dir}" />  
  297.                 <nativefolder refid="project.libraries.libs" />  
  298.                 <extra-jars />  
  299.             </apkbuilder>  
  300.         </sequential>  
  301.     </macrodef>  
  302.   
  303.     <!-- This is macro which zipaligns in.package and outputs it to out.package. Used by targets  
  304.          debug, -debug-with-emma and release.  
  305.          通過zipaligns 對APK進行優化  
  306.          -->  
  307.     <macrodef name="zipalign-helper">  
  308.         <attribute name="in.package" />  
  309.         <attribute name="out.package" />  
  310.         <sequential>  
  311.             <zipalign executable="${zipalign}" input="@{in.package}" output="@{out.package}" verbose="${verbose}" />  
  312.         </sequential>  
  313.     </macrodef>  
  314.   
  315.     <macrodef name="run-tests-helper">  
  316.         <attribute name="emma.enabled" default="false" />  
  317.         <element name="extra-instrument-args" optional="yes" />  
  318.         <sequential>  
  319.             <echo>Running tests ...</echo>  
  320.             <exec executable="${adb}" failonerror="true">  
  321.                 <arg line="${adb.device.arg}" />  
  322.                 <arg value="shell" />  
  323.                 <arg value="am" />  
  324.                 <arg value="instrument" />  
  325.                 <arg value="-w" />  
  326.                 <arg value="-e" />  
  327.                 <arg value="coverage" />  
  328.                 <arg value="@{emma.enabled}" />  
  329.                 <extra-instrument-args />  
  330.                 <arg value="${manifest.package}/${test.runner}" />  
  331.             </exec>  
  332.         </sequential>  
  333.     </macrodef>  
  334.   
  335.     <macrodef name="record-build-key">  
  336.         <attribute name="key" default="false" />  
  337.         <attribute name="value" default="false" />  
  338.         <sequential>  
  339.             <propertyfile file="${out.build.prop.file}" comment="Last build type">  
  340.                 <entry key="@{key}" value="@{value}" />  
  341.             </propertyfile>  
  342.         </sequential>  
  343.     </macrodef>  
  344.   
  345.     <macrodef name="record-build-info">  
  346.         <sequential>  
  347.             <record-build-key key="build.last.target" value="${build.target}" />  
  348.             <record-build-key key="build.last.is.instrumented" value="${build.is.instrumented}" />  
  349.             <record-build-key key="build.last.is.packaging.debug" value="${build.is.packaging.debug}" />  
  350.             <record-build-key key="build.last.is.signing.debug" value="${build.is.signing.debug}" />  
  351.         </sequential>  
  352.     </macrodef>  
  353.   
  354.     <macrodef name="uninstall-helper">  
  355.         <attribute name="app.package" default="false" />  
  356.         <sequential>  
  357.             <echo>Uninstalling @{app.package} from the default emulator or device...</echo>  
  358.             <exec executable="${adb}" failonerror="true">  
  359.                 <arg line="${adb.device.arg}" />  
  360.                 <arg value="uninstall" />  
  361.                 <arg value="@{app.package}" />  
  362.             </exec>  
  363.         </sequential>  
  364.     </macrodef>  
  365.   
  366.     <!-- ********** Build Targets ********** -->  
  367.   
  368.     <!-- this target simply force running -setup making  
  369.          the project info be read. To be used as  
  370.              ant all clean  
  371.          to clean the main project as well as the libraries and tested project  
  372.          執行-setup,在此之前必須執行clean,  
  373.           -->  
  374.     <target name="all" depends="-setup" />  
  375.   
  376.     <!-- clean target -->  
  377.     <target name="clean" description="Removes output files created by other targets.">  
  378.         <delete dir="${out.absolute.dir}" verbose="${verbose}" />  
  379.         <delete dir="${gen.absolute.dir}" verbose="${verbose}" />  
  380.   
  381.         <!-- if we know about a tested project or libraries, we clean them too. This  
  382.              will only work if the target 'all' was called first -->  
  383.         <if condition="${project.is.test}">  
  384.             <then>  
  385.                 <property name="tested.project.absolute.dir" location="${tested.project.dir}" />  
  386.                 <subant failonerror="true">  
  387.                     <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />  
  388.                     <target name="all" />  
  389.                     <target name="clean" />  
  390.                 </subant>  
  391.             </then>  
  392.         </if>  
  393.   
  394.         <if>  
  395.             <condition>  
  396.                 <isreference refid="project.libraries" />  
  397.             </condition>  
  398.             <then>  
  399.                 <!-- 有libraries關聯工程的時候,呼叫libraries工程中build.xml -->  
  400.                 <subant buildpathref="project.libraries" antfile="build.xml" failonerror="true">  
  401.                     <target name="all" />  
  402.                     <target name="clean" />  
  403.                 </subant>  
  404.             </then>  
  405.         </if>  
  406.     </target>  
  407.   
  408.     <!-- generic setup 初始化-->  
  409.     <target name="-setup">  
  410.         <if>  
  411.             <condition>  
  412.                 <not>  
  413.                     <isset property="setup.done" />  
  414.                 </not>  
  415.             </condition>  
  416.             <then>  
  417.                 <property name="setup.done" value="true" />  
  418.                 <echo>Gathering info for ${ant.project.name}...</echo>  
  419.                 <!-- load project properties, resolve Android target, library dependencies  
  420.                      and set some properties with the results.  
  421.                      All property names are passed as parameters ending in -Out  
  422.                                                             載入project properties,設定 Android target,依賴的library工程和一些其他的屬性  
  423.                       -->  
  424.                 <setup projectTypeOut="android.project.type" androidJarFileOut="android.jar" androidAidlFileOut="android.aidl" renderScriptExeOut="renderscript" renderScriptIncludeDirOut="android.rs" bootclasspathrefOut="android.target.classpath" projectLibrariesRootOut="project.libraries" projectLibrariesJarsOut="project.libraries.jars" projectLibrariesResOut="project.libraries.res" projectLibrariesPackageOut="project.libraries.package" projectLibrariesLibsOut="project.libraries.libs" targetApiOut="target.api" />  
  425.   
  426.                 <!-- sets a few boolean based on android.project.type  
  427.                      to make the if task easier -->  
  428.                 <condition property="project.is.library" else="false">  
  429.                     <equals arg1="${android.project.type}" arg2="library" />  
  430.                 </condition>  
  431.                 <condition property="project.is.test" else="false">  
  432.                     <equals arg1="${android.project.type}" arg2="test" />  
  433.                 </condition>  
  434.   
  435.                 <!-- If a test project, resolve absolute path to tested project. -->  
  436.                 <if condition="${project.is.test}">  
  437.                     <then>  
  438.                         <property name="tested.project.absolute.dir" location="${tested.project.dir}" />  
  439.                     </then>  
  440.                 </if>  
  441.             </then>  
  442.         </if>  
  443.     </target>  
  444.   
  445.     <!-- Pre build setup   
  446.     預編譯  
  447.     -->  
  448.     <target name="-build-setup" depends="-setup">  
  449.   
  450.         <!-- read the previous build mode -->  
  451.         <property file="${out.build.prop.file}" />  
  452.         <!-- if empty the prop won't be set, so set it to the current target  
  453.              to provide a default value equal to the current build -->  
  454.         <property name="build.last.target" value="${build.target}" />  
  455.         <!-- also set the default value for whether the build is instrumented -->  
  456.         <property name="build.last.is.instrumented" value="${build.is.instrumented}" />  
  457.         <property name="build.last.is.packaging.debug" value="${build.is.packaging.debug}" />  
  458.         <property name="build.last.is.signing.debug" value="${build.is.signing.debug}" />  
  459.   
  460.         <!-- compile the libraries if any  
  461.         編譯libraries  
  462.          -->  
  463.         <if>  
  464.             <condition>  
  465.                 <isreference refid="project.libraries" />  
  466.             </condition>  
  467.             <then>  
  468.                 <echo>Building Libraries</echo>  
  469.                 <subant buildpathref="project.libraries" antfile="build.xml" target="${build.target}" failonerror="true" />  
  470.                 <echo>  
  471.                 </echo>  
  472.                 <echo>############################################</echo>  
  473.                 <echo>**** Back to project ${ant.project.name} ****</echo>  
  474.                 <echo>############################################</echo>  
  475.             </then>  
  476.         </if>  
  477.   
  478.         <!-- compile the main project if this is a test project  
  479.         編譯主工程,如果這是測試工程  
  480.          -->  
  481.         <if condition="${project.is.test}">  
  482.             <then>  
  483.                 <!-- figure out which target must be used to build the tested project.  
  484.                      If emma is enabled, then use 'instrument' otherwise, use 'debug' -->  
  485.                 <condition property="tested.project.target" value="instrument" else="debug">  
  486.                     <isset property="emma.enabled" />  
  487.                 </condition>  
  488.   
  489.                 <echo>Building tested project at ${tested.project.absolute.dir}</echo>  
  490.                 <subant target="${tested.project.target}" failonerror="true">  
  491.                     <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />  
  492.                 </subant>  
  493.                 <echo>  
  494.                 </echo>  
  495.                 <echo>############################################</echo>  
  496.                 <echo>**** Back to project ${ant.project.name} ****</echo>  
  497.                 <echo>############################################</echo>  
  498.             </then>  
  499.         </if>  
  500.   
  501.         <!-- Value of the hasCode attribute (Application node) extracted from manifest file -->  
  502.         <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode" output="manifest.hasCode" default="true" />  
  503.   
  504.         <!-- create a path with all the jar files, from the main project and the  
  505.              libraries   
  506.                                        建立一個path,關聯所有的jar檔案。每個工程下的libs下的jar檔案  
  507.              -->  
  508.         <path id="jar.libs.ref">  
  509.             <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" />  
  510.             <path refid="project.libraries.jars" />  
  511.         </path>  
  512.   
  513.         <!-- special case for instrumented: if the previous build was  
  514.              instrumented but not this one, clear out the compiled code   
  515.              特殊情況被打斷,清除已編譯的程式碼  
  516.              -->  
  517.         <if>  
  518.             <condition>  
  519.                 <and>  
  520.                     <istrue value="${build.last.is.instrumented}" />  
  521.                     <isfalse value="${build.is.instrumented}" />  
  522.                 </and>  
  523.             </condition>  
  524.             <then>  
  525.                 <echo>Switching from instrumented to non-instrumented build.</echo>  
  526.                 <echo>Deleting previous compilation output:</echo>  
  527.                 <delete dir="${out.classes.absolute.dir}" verbose="${verbose}" />  
  528.             </then>  
  529.         </if>  
  530.   
  531.         <echo>Creating output directories if needed...</echo>  
  532.         <mkdir dir="${resource.absolute.dir}" />  
  533.         <mkdir dir="${jar.libs.absolute.dir}" />  
  534.         <mkdir dir="${out.absolute.dir}" />  
  535.         <mkdir dir="${out.res.absolute.dir}" />  
  536.         <do-only-if-manifest-hasCode>  
  537.             <mkdir dir="${gen.absolute.dir}" />  
  538.             <mkdir dir="${out.classes.absolute.dir}" />  
  539.         </do-only-if-manifest-hasCode>  
  540.     </target>  
  541.   
  542.     <!-- empty default pre-build target. Create a similar target in  
  543.          your build.xml and it'll be called instead of this one. -->  
  544.     <target name="-pre-build" />  
  545.   
  546.     <!-- Code Generation: compile resources (aapt -> R.java), aidl, renderscript  
  547.     通過appt 生成R.jar檔案  
  548.      -->  
  549.     <target name="-code-gen">  
  550.         <do-only-if-manifest-hasCode elseText="hasCode = false. Skipping aidl/renderscript/R.java">  
  551.             <echo>----------</echo>  
  552.             <echo>Handling aidl files...</echo>  
  553.             <aidl executable="${aidl}" framework="${android.aidl}" genFolder="${gen.absolute.dir}">  
  554.                 <source path="${source.absolute.dir}" />  
  555.             </aidl>  
  556.   
  557.             <!-- renderscript generates resources so it must be called before aapt -->  
  558.             <echo>----------</echo>  
  559.             <echo>Handling RenderScript files...</echo>  
  560.             <renderscript executable="${renderscript}" framework="${android.rs}" genFolder="${gen.absolute.dir}" resFolder="${resource.absolute.dir}/raw" targetApi="${target.api}">  
  561.                 <source path="${source.absolute.dir}" />  
  562.             </renderscript>  
  563.   
  564.             <echo>----------</echo>  
  565.             <echo>Handling Resources...</echo>  
  566.             <aapt executable="${aapt}" command="package" verbose="${verbose}" manifest="AndroidManifest.xml" androidjar="${android.jar}" rfolder="${gen.absolute.dir}" nonConstantId="${android.library}" projectLibrariesResName="project.libraries.res" projectLibrariesPackageName="project.libraries.package">  
  567.                 <res path="${resource.absolute.dir}" />  
  568.             </aapt>  
  569.         </do-only-if-manifest-hasCode>  
  570.     </target>  
  571.   
  572.     <!-- empty default pre-compile target. Create a similar target in  
  573.          your build.xml and it'll be called instead of this one. -->  
  574.     <target name="-pre-compile" />  
  575.   
  576.     <!-- Compiles this project's .java files into .class files.   
  577.     編譯  
  578.     -->  
  579.     <target name="-compile" depends="-build-setup, -pre-build, -code-gen, -pre-compile">  
  580.         <do-only-if-manifest-hasCode elseText="hasCode = false. Skipping...">  
  581.             <!-- If android rules are used for a test project, its classpath should include  
  582.                  tested project's location   
  583.                  如果是測試工程,classpath應該包括test的位置  
  584.                  -->  
  585.             <condition property="extensible.classpath" value="${tested.project.absolute.dir}/bin/classes" else=".">  
  586.                 <isset property="tested.project.absolute.dir" />  
  587.             </condition>  
  588.             <condition property="extensible.libs.classpath" value="${tested.project.absolute.dir}/${jar.libs.dir}" else="${jar.libs.dir}">  
  589.                 <isset property="tested.project.absolute.dir" />  
  590.             </condition>  
  591.             <javac encoding="${java.encoding}" source="${java.source}" target="${java.target}" debug="true" extdirs="" destdir="${out.classes.absolute.dir}" bootclasspathref="android.target.classpath" verbose="${verbose}" classpath="${extensible.classpath}" classpathref="jar.libs.ref">  
  592.                 <src path="${source.absolute.dir}" />  
  593.                 <src path="${gen.absolute.dir}" />  
  594.                 <classpath>  
  595.                     <fileset dir="${extensible.libs.classpath}" includes="*.jar" />  
  596.                 </classpath>  
  597.             </javac>  
  598.             <!-- if the project is a library then we generate a jar file   
  599.             如果工程是library工程,則生成jar檔案  
  600.             -->  
  601.             <if condition="${project.is.library}">  
  602.                 <then>  
  603.                     <echo>Creating library output jar file...</echo>  
  604.                     <property name="out.library.jar.file" location="${out.absolute.dir}/classes.jar" />  
  605.                     <if>  
  606.                         <condition>  
  607.                             <length string="${android.package.excludes}" trim="true" when="greater" length="0" />  
  608.                         </condition>  
  609.                         <then>  
  610.                             <echo>Custom jar packaging exclusion: ${android.package.excludes}

相關文章