使用ant優化android專案編譯速度,提高工作效率

weixin_34402090發表於2013-12-11

1、Android專案編譯週期長,編譯專案命令取消困難

2、在進行Android專案的編譯的同時,Eclipse鎖定工作區不能進行修改操作

3、在只進行資原始檔的修改時,Eclipse對資原始檔的修改會導致整個專案的編譯,在無法開啟自動編譯模式下,極為不便

對專案進行分包處理後,android編譯速度極慢。

對於我們現在的專案,在未進行分包時編譯一次大約需要4、5分鐘而有時候你只是簡單的修改了一下java檔案。。。

進行分包後,編譯整個專案時長達到10分以上,有時甚至造成eclipse假死

嚴重的損耗了工作時間和降低工作效率。

針對現在生成專案速度慢的狀況,發現android 專案編譯時對資原始檔的操作佔大量時間。

Eclipse預設編譯流程會有兩次aapt呼叫。每次時間約四分鐘。

針對我們進行android專案開發時的經驗,有以下幾種情況:

1、頻繁更改資原始檔,在類中需要引用資源但不用生成apk

2、頻繁修改java類檔案,資原始檔不變,需要生成apk

3、次數很少的同時修改資原始檔和java類檔案,同時生成apk 

使用ant build 指令碼實現將二次資原始檔的操作分開,可以良好改善編譯速度,提高工作效率(至少一半)。在ant指令碼編譯模式下,對於以上三種情況:

1、在只有資原始檔更改的情況 :使用命令 ant generateR 只更新R檔案 耗時 約4mins

2、在沒有更新資原始檔後,只修改JAVA類,使用 ant simpledebug 忽略資原始檔R引用的更新,並打包 耗時 約5mins

3、更新了資原始檔,又修改了JAVA檔案想立即打包則使用ant debug 此為Eclipse預設模式,時長 大約10minus  -_-| 

以下為ant build優化,大家可以參考一下

<?xml version="1.0" encoding="UTF-8"?>
<project name="Reader" >

<!-- The local.properties file is created and updated by the 'android'
     tool.
     It contains the path to the SDK. It should *NOT* be checked into
     Version Control Systems. -->
    <property file="local.properties" />

    <!-- The build.properties file can be created by you and is never touched
         by the 'android' tool. This is the place to change some of the
         default property values used by the Ant rules.
         Here are some properties you may want to change/update:

         source.dir
             The name of the source directory. Default is 'src'.
         out.dir
             The name of the output directory. Default is 'bin'.

         Properties related to the SDK location or the project target should
         be updated using the 'android' tool with the 'update' action.

         This file is an integral part of the build system for your
         application and should be checked into Version Control Systems.

         -->
    <property file="build.properties" />

    <!-- The default.properties file is created and updated by the 'android'
         tool, as well as ADT.
         This file is an integral part of the build system for your
         application and should be checked into Version Control Systems. -->
    <property file="default.properties" />

    <!-- Custom Android task to deal with the project target, and import the
         proper rules.
         This requires ant 1.6.0 or above. -->
    <path id="android.antlibs">
        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
    </path>

    <taskdef name="setup"
        classname="com.android.ant.SetupTask"
        classpathref="android.antlibs" />

<!-- extension targets. Uncomment the ones where you want to do custom work
     in between standard targets -->
<!--
    <target name="-pre-build">
    </target>
    <target name="-pre-compile">
    </target>

    [This is typically used for code obfuscation.
     Compiled code location: ${out.classes.absolute.dir}
     If this is not done in place, override ${out.dex.input.absolute.dir}]
    <target name="-post-compile">
    </target>
-->


    <!-- Execute the Android Setup task that will setup some properties
         specific to the target, and import the build rules files.

         The rules file is imported from
            <SDK>/platforms/<target_platform>/ant/ant_rules_r#.xml

         To customize existing targets, there are two options:
         - Customize only one target:
             - copy/paste the target into this file, *before* the
               <setup> task.
             - customize it to your needs.
         - Customize the whole script.
             - copy/paste the content of the rules files (minus the top node)
               into this file, *after* the <setup> task
             - disable the import of the rules by changing the setup task
               below to <setup import="false" />. 
             - customize to your needs.
    -->
    <setup import="false"/>
    <!--
            This rules file is meant to be imported by the custom Ant task:
                com.android.ant.SetupTask

            The following properties are put in place by the importing task:
                android.jar, android.aidl, aapt, aidl, and dx

            Additionnaly, the task sets up the following classpath reference:
                android.target.classpath
            This is used by the compiler task as the boot classpath.
        -->

        <!-- Custom tasks -->
        <taskdef name="aapt"
            classname="com.android.ant.AaptExecLoopTask"
            classpathref="android.antlibs" />

        <taskdef name="aidl"
            classname="com.android.ant.AidlExecTask"
            classpathref="android.antlibs" />

        <taskdef name="apkbuilder"
            classname="com.android.ant.ApkBuilderTask"
            classpathref="android.antlibs" />

        <taskdef name="xpath"
            classname="com.android.ant.XPathTask"
            classpathref="android.antlibs" />

        <taskdef name="if"
            classname="com.android.ant.IfElseTask"
            classpathref="android.antlibs" />
        
        <taskdef name="nowtime" classname="AntNowTime" classpath="."/>
        <!-- Properties -->

        <!-- Tells adb which device to target. You can change this from the command line
             by invoking "ant -Dadb.device.arg=-d" for device "ant -Dadb.device.arg=-e" for
             the emulator. -->
        <property name="adb.device.arg" value="" />

        <property name="android.tools.dir" location="${sdk.dir}/tools" />
        <!-- Name of the application package extracted from manifest file -->
        <xpath input="AndroidManifest.xml" expression="/manifest/@package"
                    output="manifest.package" />
        <!-- Value of the debuggable attribute (Application node) extracted from manifest file -->
        <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable"
                    output="manifest.debuggable" default="false"/>
        <!-- Value of the debuggable attribute (Application node) extracted from manifest file -->
        <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode"
                    output="manifest.hasCode" default="true"/>

        <!-- Input directories -->
        <property name="source.dir" value="src" />
        <property name="source.absolute.dir" location="${source.dir}" />
        <property name="gen.dir" value="gen" />
        <property name="gen.absolute.dir" location="${gen.dir}" />
        <property name="resource.dir" value="res" />
        <property name="resource.absolute.dir" location="${resource.dir}" />
        <property name="asset.dir" value="assets" />
        <property name="asset.absolute.dir" location="${asset.dir}" />

        <!-- Directory for the third party java libraries -->
        <property name="external.libs.dir" value="${reader_libs}" />
        <property name="external.libs.absolute.dir" location="${external.libs.dir}" />

        <!-- Directory for the native libraries -->
        <property name="native.libs.dir" value="libs" />
        <property name="native.libs.absolute.dir" location="${native.libs.dir}" />

        <!-- Output directories -->
        <property name="out.dir" value="bin" />
        <property name="out.absolute.dir" location="${out.dir}" />
        <property name="out.classes.dir" value="${out.absolute.dir}" />
        <property name="out.classes.absolute.dir" location="${out.classes.dir}" />
        <property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />

        <!-- Intermediate files -->
        <property name="dex.file.name" value="classes.dex" />
        <property name="intermediate.dex.file"
                      location="${out.absolute.dir}/${dex.file.name}" />
        <property name="resource.package.file.name"
                      value="${ant.project.name}.ap_" />

        <!-- The final package file to generate
             These can be overridden by setting them earlier to
             different values -->
        <property name="out.debug.unaligned.file"
                      location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk" />
        <property name="out.debug.file"
                      location="${out.absolute.dir}/${ant.project.name}-debug.apk" />

        <property name="out.unsigned.file.name"
                      value="${ant.project.name}-unsigned.apk" />
        <property name="out.unsigned.file"
                      location="${out.absolute.dir}/${out.unsigned.file.name}" />

        <property name="out.unaligned.file.name"
                      value="${ant.project.name}-unaligned.apk" />
        <property name="out.unaligned.file"
                      location="${out.absolute.dir}/${out.unaligned.file.name}" />

        <property name="out.release.file.name"
                      value="${ant.project.name}-release.apk" />
        <property name="out.release.file"
                      location="${out.absolute.dir}/${out.release.file.name}" />

        <!-- set some properties used for filtering/override. If those weren't defined
             before, then this will create them with empty values, which are then ignored
             by the custom tasks receiving them. -->
        <property name="version.code" value="" />
        <property name="aapt.resource.filter" value="" />
        <property name="filter.abi" value="" />

        <!-- Verbosity -->
        <property name="verbose" value="false" />
        <!-- This is needed by emma as it uses multilevel verbosity instead of simple 'true' or 'false'
             The property 'verbosity' is not user configurable and depends exclusively on 'verbose'
             value.-->
        <condition property="verbosity" value="verbose" else="quiet">
            <istrue value="${verbose}" />
        </condition>
        <!-- This is needed to switch verbosity of zipalign. Depends exclusively on 'verbose'
             -->
        <condition property="v.option" value="-v" else="">
            <istrue value="${verbose}" />
        </condition>
        <!-- This is needed to switch verbosity of dx. Depends exclusively on 'verbose' -->
        <condition property="verbose.option" value="--verbose" else="">
            <istrue value="${verbose}" />
        </condition>

        <!-- properties for signing in release mode -->
        <condition property="has.keystore">
            <and>
                <isset property="key.store" />
                <length string="${key.store}" when="greater" length="0" />
                <isset property="key.alias" />
            </and>
        </condition>
        <condition property="has.password">
            <and>
                <isset property="has.keystore" />
                <isset property="key.store.password" />
                <isset property="key.alias.password" />
            </and>
        </condition>

        <!-- Tools -->
        <condition property="exe" value=".exe" else=""><os family="windows" /></condition>
        <property name="adb" location="${android.tools.dir}/adb${exe}" />
        <property name="zipalign" location="${android.tools.dir}/zipalign${exe}" />

        <!-- Emma configuration -->
        <property name="emma.dir" value="${sdk.dir}/tools/lib" />
            <path id="emma.lib">
                <pathelement location="${emma.dir}/emma.jar" />
                <pathelement location="${emma.dir}/emma_ant.jar" />
            </path>
        <taskdef resource="emma_ant.properties" classpathref="emma.lib" />
        <!-- End of emma configuration -->

        <!-- Macros -->

        <!-- Configurable macro, which allows to pass as parameters output directory,
             output dex filename and external libraries to dex (optional) -->
        <macrodef name="dex-helper">
           <element name="external-libs" optional="yes" />
           <element name="extra-parameters" optional="yes" />
           <sequential>
             <echo>Converting compiled files and external libraries into ${intermediate.dex.file}...</echo>
             <apply executable="${dx}" failonerror="true" parallel="true">
                 <arg value="--dex" />
                 <arg value="--output=${intermediate.dex.file}" />
                 <extra-parameters />
                 <arg line="${verbose.option}" />
                 <arg path="${out.dex.input.absolute.dir}" />
                 <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
                 <path refid="android.libraries.jars" />
                 <external-libs />
             </apply>
           </sequential>
        </macrodef>

        <!-- This is macro that enable passing variable list of external jar files to ApkBuilder
             Example of use:
             <package-helper sign.package="true" output.filepath="/path/to/foo.apk">
                 <extra-jars>
                    <jarfolder path="my_jars" />
                    <jarfile path="foo/bar.jar" />
                    <jarfolder path="your_jars" />
                 </extra-jars>
             </package-helper> -->
        <macrodef name="package-helper">
            <attribute name="sign.package" />
            <attribute name="output.filepath" />
            <element name="extra-jars" optional="yes" />
            <sequential>
                <apkbuilder
                        outfolder="${out.absolute.dir}"
                        resourcefile="${resource.package.file.name}"
                        apkfilepath="@{output.filepath}"
                        signed="@{sign.package}"
                        debug="${manifest.debuggable}"
                        abifilter="${filter.abi}"
                        verbose="${verbose}"
                        hascode="${manifest.hasCode}">
                    <dex path="${intermediate.dex.file}"/>
                    <sourcefolder path="${source.absolute.dir}"/>
                    <sourcefolder refid="android.libraries.src"/>
                    <jarfolder path="${external.libs.absolute.dir}" />
                    <jarfolder refid="android.libraries.libs" />
                    <nativefolder path="${native.libs.absolute.dir}" />
                    <nativefolder refid="android.libraries.libs" />
                    <extra-jars/>
                </apkbuilder>
            </sequential>
        </macrodef>

        <!-- This is macro which zipaligns in.package and outputs it to out.package. Used by targets
             debug, -debug-with-emma and release.-->
        <macrodef name="zipalign-helper">
            <attribute name="in.package" />
            <attribute name="out.package" />
            <sequential>
                <echo>Running zip align on final apk...</echo>
                <exec executable="${zipalign}" failonerror="true">
                    <arg line="${v.option}" />
                    <arg value="-f" />
                    <arg value="4" />
                    <arg path="@{in.package}" />
                    <arg path="@{out.package}" />
                </exec>
            </sequential>
        </macrodef>

        <!-- This is macro used only for sharing code among two targets, -install and
             -install-with-emma which do exactly the same but differ in dependencies -->
        <macrodef name="install-helper">
            <sequential>
                <echo>Installing ${out.debug.file} onto default emulator or device...</echo>
                <exec executable="${adb}" failonerror="true">
                    <arg line="${adb.device.arg}" />
                    <arg value="install" />
                    <arg value="-r" />
                    <arg path="${out.debug.file}" />
                </exec>
            </sequential>
        </macrodef>

        <!-- Rules -->
        
    
        <target name="use" description="Use the Task" >
            <nowtime/>
        </target>
        <!-- Creates the output directories if they don't exist yet. -->
        <target name="-dirs">
            <echo>Creating output directories if needed...</echo>
            <mkdir dir="${resource.absolute.dir}" />
            <mkdir dir="${external.libs.absolute.dir}" />
            <mkdir dir="${out.absolute.dir}" />
            <if condition="${manifest.hasCode}">
                <then>
                    <mkdir dir="${gen.absolute.dir}" />
                    <mkdir dir="${out.classes.absolute.dir}" />
                </then>
            </if>
        </target>

        <!-- empty default pre-build target. Create a similar target in
             your build.xml and it'll be called instead of this one. -->
        <target name="-pre-build"/>

        <!-- Generates the R.java file for this project's resources. -->
        <target name="generateR" depends="cleanR,-dirs, -pre-build">
            <if condition="${manifest.hasCode}">
                <then>
                    <echo>Generating R.java / Manifest.java from the resources...</echo>
                    <nowtime/>
                    <aapt executable="${aapt}"
                                            command="package"
                                            verbose="${verbose}"
                                            manifest="AndroidManifest.xml"
                                            androidjar="${android.jar}"
                                            rfolder="${gen.absolute.dir}">
                                        <res path="${resource.absolute.dir}" />
                                    </aapt>
                    <nowtime/>
                </then>
                <else>
                    <echo>hasCode = false. Skipping...</echo>
                </else>
            </if>
        </target>

        <!-- Generates java classes from .aidl files. -->
        <target name="-aidl" depends="-dirs">
            <if condition="${manifest.hasCode}">
                <then>
                    <echo>Compiling aidl files into Java classes...</echo>
                    <aidl executable="${aidl}" framework="${android.aidl}"
                            genFolder="${gen.absolute.dir}">
                        <source path="${source.absolute.dir}"/>
                        <source refid="android.libraries.src"/>
                    </aidl>
                </then>
                <else>
                    <echo>hasCode = false. Skipping...</echo>
                </else>
            </if>
        </target>

        <!-- empty default pre-compile target. Create a similar target in
             your build.xml and it'll be called instead of this one. -->
        <target name="-pre-compile"/>

        <!-- Compiles this project's .java files into .class files. -->
        <target name="compile" depends="generateR, -aidl, -pre-compile"
                    description="Compiles project's .java files into .class files">
            <if condition="${manifest.hasCode}">
                <then>
                    <!-- If android rules are used for a test project, its classpath should include
                         tested project's location -->
                    <condition property="extensible.classpath"
                            value="${tested.project.absolute.dir}/bin/classes"
                            else=".">
                        <isset property="tested.project.absolute.dir" />
                    </condition>
                    <condition property="extensible.libs.classpath"
                            value="${tested.project.absolute.dir}/libs"
                            else="./libs">
                        <isset property="tested.project.absolute.dir" />
                    </condition>
                    <javac encoding="GBK" target="1.5" debug="true" extdirs=""
                            destdir="${out.classes.absolute.dir}"
                            bootclasspathref="android.target.classpath"
                            verbose="${verbose}"
                            classpath="${extensible.classpath}"
                            classpathref="android.libraries.jars">
                        <src path="${reader_service_project}/src"  />
                        <src path="${reader_data_project}/src" />
                        <src path="${reader_service_project}/gen"  />
                        <src path="${reader_data_project}/gen" />
                        <src path="${source.absolute.dir}" />
                        <src path="${gen.absolute.dir}" />
                        <src refid="android.libraries.src" />
                        <classpath>
                            <fileset dir="${reader_lib_project}/lib" includes="*.jar" />
                            <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
                            <fileset dir="${extensible.libs.classpath}" includes="*.jar" />
                        </classpath>
                    </javac>
                </then>
                <else>
                    <echo>hasCode = false. Skipping...</echo>
                </else>
            </if>
        </target>
        
    <!-- Compiles this project's .java files into .class files. -->
            <target name="simplecompile" depends="-pre-compile"
                        description="Compiles project's .java files into .class files">
                <echo>simplecompile start at time</echo><nowtime/>
                <if condition="${manifest.hasCode}">
                    <then>
                        <!-- If android rules are used for a test project, its classpath should include
                             tested project's location -->
                        <condition property="extensible.classpath"
                                value="${tested.project.absolute.dir}/bin/classes"
                                else=".">
                            <isset property="tested.project.absolute.dir" />
                        </condition>
                        <condition property="extensible.libs.classpath"
                                value="${tested.project.absolute.dir}/libs"
                                else="./libs">
                            <isset property="tested.project.absolute.dir" />
                        </condition>
                        <javac encoding="GBK" target="1.5" debug="true" extdirs=""
                                destdir="${out.classes.absolute.dir}"
                                bootclasspathref="android.target.classpath"
                                verbose="${verbose}"
                                classpath="${extensible.classpath}"
                                classpathref="android.libraries.jars">
                            <src path="${reader_service_project}/src"  />
                            <src path="${reader_data_project}/src" />
                            <src path="${reader_service_project}/gen"  />
                            <src path="${reader_data_project}/gen" />
                            <src path="${source.absolute.dir}" />
                            <src path="${gen.absolute.dir}" />
                            <src refid="android.libraries.src" />
                            <classpath>
                                <fileset dir="${reader_lib_project}/lib" includes="*.jar" />
                                <fileset dir="${external.libs.absolute.dir}" includes="*.jar" />
                                <fileset dir="${extensible.libs.classpath}" includes="*.jar" />
                            </classpath>
                        </javac>
                    </then>
                    <else>
                        <echo>hasCode = false. Skipping...</echo>
                    </else>
                </if>
                <echo>simplecompile end at time</echo><nowtime/> 
            </target>
        
        <!-- empty default post-compile target. Create a similar target in
             your build.xml and it'll be called instead of this one. -->
        <target name="-post-compile"/>

        <!-- Converts this project's .class files into .dex files -->
        <target name="-dex" depends="simplecompile, -post-compile"
                unless="do.not.compile">
            <if condition="${manifest.hasCode}">
                <then>
                    <dex-helper />
                </then>
                <else>
                    <echo>hasCode = false. Skipping...</echo>
                </else>
            </if>
        </target>
    
      <!-- Converts this project's .class files into .dex files -->
            <target name="-simpledex" depends="simplecompile, -post-compile"
                    unless="do.not.compile">
                <echo>-simpledex start at time</echo><nowtime/> 
                <if condition="${manifest.hasCode}">
                    <then>
                        <dex-helper />
                    </then>
                    <else>
                        <echo>hasCode = false. Skipping...</echo>
                    </else>
                </if>
                <echo>-simpledex end at time</echo><nowtime/>  
           </target>

        <!-- Puts the project's resources into the output package file
             This actually can create multiple resource package in case
             Some custom apk with specific configuration have been
             declared in default.properties.
             -->
        <target name="-package-resources">
            <echo>Packaging resources start at time</echo>
            <echo>Packaging resources start at time</echo><nowtime/>  
            <aapt executable="${aapt}"
                    command="package"
                    versioncode="${version.code}"
                    manifest="AndroidManifest.xml"
                    assets="${asset.absolute.dir}"
                    androidjar="${android.jar}"
                    apkfolder="${out.absolute.dir}"
                    resourcefilename="${resource.package.file.name}"
                    resourcefilter="${aapt.resource.filter}">
                <res path="${resource.absolute.dir}" />
                <!-- <nocompress /> forces no compression on any files in assets or res/raw -->
                <!-- <nocompress extension="xml" /> forces no compression on specific file extensions in assets and res/raw -->
            </aapt>
            <echo>Packaging resources end at time</echo><nowtime/>
        </target>

        <!-- Packages the application and sign it with a debug key. -->
        <target name="-package-debug-sign" depends="-dex, -package-resources">
            <package-helper
                    sign.package="true"
                    output.filepath="${out.debug.unaligned.file}" />
        </target>
    
        <!-- Packages the application and sign it with a debug key. -->
            <target name="-simplepackage-debug-sign" depends="-simpledex, -package-resources">
                <package-helper
                        sign.package="true"
                        output.filepath="${out.debug.unaligned.file}" />
        </target>

        <!-- Packages the application without signing it. -->
        <target name="-package-release" depends="-dex, -package-resources">
            <package-helper
                    sign.package="false"
                    output.filepath="${out.unsigned.file}"/>
        </target>

        <target name="-compile-tested-if-test" if="tested.project.dir" unless="do.not.compile.again">
           <subant target="compile">
                <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
           </subant>
        </target>
    
        <target name="-simplecompile-tested-if-test" if="tested.project.dir" unless="do.not.compile.again">
               <subant target="simplecompile">
                    <fileset dir="${tested.project.absolute.dir}" includes="build.xml" />
               </subant>
         </target>

        <!-- Builds debug output package, provided all the necessary files are already dexed -->
        <target name="debug" depends="-compile-tested-if-test, -package-debug-sign"
                    description="Builds the application and signs it with a debug key.">
            <zipalign-helper in.package="${out.debug.unaligned.file}"
                                       out.package="${out.debug.file}" />
            <echo>Debug Package: ${out.debug.file}</echo>
        </target>
    
        <!-- Builds debug output package, provided all the necessary files are already dexed -->
        <target name="simpledebug" depends="-simplecompile-tested-if-test, -simplepackage-debug-sign"
                        description="Builds the application and signs it with a debug key.">
            <echo>Debug Package: ${out.debug.unaligned.file}</echo>   
            <!-- 
            <zipalign-helper in.package="${out.debug.unaligned.file}"
                                           out.package="${out.debug.file}" />
                <echo>Debug Package: ${out.debug.file}</echo>
                -->
        </target>

        <!-- called through target 'release'. Only executed if the keystore and
             key alias are known but not their password. -->
        <target name="-release-prompt-for-password" if="has.keystore" unless="has.password">
            <!-- Gets passwords -->
            <input
                    message="Please enter keystore password (store:${key.store}):"
                    addproperty="key.store.password" />
            <input
                    message="Please enter password for alias '${key.alias}':"
                    addproperty="key.alias.password" />
        </target>

        <!-- called through target 'release'. Only executed if there's no
             keystore/key alias set -->
        <target name="-release-nosign" unless="has.keystore">
            <echo>No key.store and key.alias properties found in build.properties.</echo>
            <echo>Please sign ${out.unsigned.file} manually</echo>
            <echo>and run zipalign from the Android SDK tools.</echo>
        </target>

        <target name="-set-release-mode">
            <property name="build.mode.release" value="true"/>
        </target>

        <!-- This runs -package-release and -release-nosign first and then runs
             only if release-sign is true (set in -release-check,
             called by -release-no-sign)-->
        <target name="release"
                    depends="-set-release-mode, -package-release, -release-prompt-for-password, -release-nosign"
                    if="has.keystore"
                    description="Builds the application. The generated apk file must be signed before
                                it is published.">
            <!-- Signs the APK -->
            <echo>Signing final apk...</echo>
            <signjar
                    jar="${out.unsigned.file}"
                    signedjar="${out.unaligned.file}"
                    keystore="${key.store}"
                    storepass="${key.store.password}"
                    alias="${key.alias}"
                    keypass="${key.alias.password}"
                    verbose="${verbose}" />

            <!-- Zip aligns the APK -->
            <zipalign-helper in.package="${out.unaligned.file}"
                                       out.package="${out.release.file}" />
            <echo>Release Package: ${out.release.file}</echo>
        </target>

        <target name="install" depends="debug"
                    description="Installs/reinstalls the debug package onto a running
                                emulator or device. If the application was previously installed,
                                the signatures must match." >
            <install-helper />
        </target>

        <target name="-uninstall-check">
            <condition property="uninstall.run">
               <isset property="manifest.package" />
            </condition>
        </target>

        <target name="-uninstall-error" depends="-uninstall-check" unless="uninstall.run">
            <echo>Unable to run 'ant uninstall', manifest.package property is not defined.
            </echo>
        </target>

        <!-- Uninstalls the package from the default emulator/device -->
        <target name="uninstall" depends="-uninstall-error" if="uninstall.run"
                    description="Uninstalls the application from a running emulator or device.">
            <echo>Uninstalling ${manifest.package} from the default emulator or device...</echo>
            <exec executable="${adb}" failonerror="true">
                <arg line="${adb.device.arg}" />
                <arg value="uninstall" />
                <arg value="${manifest.package}" />
            </exec>
        </target>

        <target name="clean" description="Removes output files created by other targets.">
            <delete dir="${out.absolute.dir}" verbose="${verbose}" />
            <delete dir="${gen.absolute.dir}" verbose="${verbose}" />
        </target>
       <target name="cleanR" description="Removes R.java file created by other targets.">
                <delete dir="${gen.absolute.dir}" verbose="${verbose}" />
        </target>
        <!-- Targets for code-coverage measurement purposes, invoked from external file -->

        <!-- Emma-instruments tested project classes (compiles the tested project if necessary)
                 and writes instrumented classes to ${instrumentation.absolute.dir}/classes -->
        <target name="-emma-instrument" depends="compile">
            <echo>Instrumenting classes from ${out.absolute.dir}/classes...</echo>
            <!-- It only instruments class files, not any external libs -->
            <emma enabled="true">
                <instr verbosity="${verbosity}"
                       mode="overwrite"
                       instrpath="${out.absolute.dir}/classes"
                       outdir="${out.absolute.dir}/classes">
                </instr>
                <!-- TODO: exclusion filters on R*.class and allowing custom exclusion from
                     user defined file -->
            </emma>
        </target>

        <target name="-dex-instrumented" depends="-emma-instrument">
           <dex-helper>
              <extra-parameters>
                <arg value="--no-locals" />
              </extra-parameters>
              <external-libs>
                <fileset file="${emma.dir}/emma_device.jar" />
              </external-libs>
           </dex-helper>
        </target>

        <!-- Invoked from external files for code coverage purposes -->
        <target name="-package-with-emma" depends="-dex-instrumented, -package-resources">
            <package-helper
                    sign.package="true"
                    output.filepath="${out.debug.unaligned.file}">
                <extra-jars>
                    <!-- Injected from external file -->
                    <jarfile path="${emma.dir}/emma_device.jar" />
                </extra-jars>
            </package-helper>
        </target>

        <target name="-debug-with-emma" depends="-package-with-emma">
            <zipalign-helper in.package="${out.debug.unaligned.file}"
                                       out.package="${out.debug.file}" />
        </target>

        <target name="-install-with-emma" depends="-debug-with-emma">
            <install-helper />
        </target>

        <!-- End of targets for code-coverage measurement purposes -->

        <target name="help">
            
            <echo>Modified Android Ant Build. Available targets:</echo>
            <echo>   generateR:     Generates the R.java file for this project's resources.</echo>        
            <echo>   simplecompile:   Compiles project's .java files into .class files.</echo>
            <echo>   simpledebug:     Builds the application and signs it with a debug key.</echo>
        
            <!-- displays starts at col 13
                  |13                                                              80| -->
            <echo>Android Ant Build. Available targets:</echo>
            <echo>   help:      Displays this help.</echo>
            <echo>   clean:     Removes output files created by other targets.</echo>
            <echo>   compile:   Compiles project's .java files into .class files.</echo>
            <echo>   debug:     Builds the application and signs it with a debug key.</echo>
            <echo>   release:   Builds the application. The generated apk file must be</echo>
            <echo>              signed before it is published.</echo>
            <echo>   install:   Installs/reinstalls the debug package onto a running</echo>
            <echo>              emulator or device.</echo>
            <echo>              If the application was previously installed, the</echo>
            <echo>              signatures must match.</echo>
            <echo>   uninstall: Uninstalls the application from a running emulator or</echo>
            <echo>              device.</echo>
        </target>
    
    
</project>
View Code

相關文章