通过ant脚本,编译打包android工程
通过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签名。
通过命令打包的脚本:见附件bulid0.xml,这个ant脚本只能编译打包一个单独的android工程或依赖一个library 的android工程
- <?xmlversion="1.0"encoding="UTF-8"?>
- <projectname="ant"default="release">
- <!--ANT环境变量-->
- <propertyenvironment="env"/>
- <!--应用名称-->
- <propertyname="appName"value="TestPack"/>
- <propertyname="basedir"value=""/>
- <propertyname="library-dir"value="">
- </property>
- <!--SDK目录(获取操作系统环境变量ANDROID_SDK_HOME的值)-->
- <!--<propertyname="sdk-folder"value="${env.ANDROID_SDK_HOME}"/>-->
- <propertyname="sdk-folder"value=""/>
- <!--SDK指定平台目录-->
- <propertyname="sdk-platform-folder"value="${sdk-folder}/platforms/android-4"/>
- <!--SDK中tools目录-->
- <propertyname="sdk-tools"value="${sdk-folder}/tools"/>
- <!--SDK指定平台中tools目录-->
- <propertyname="sdk-platform-tools"value="${sdk-folder}/platform-tools"/>
- <!--使用到的命令(当前系统为windows,如果系统为linux,可将.bat文件替换成相对应的命令)-->
- <propertyname="aapt"value="${sdk-platform-tools}/aapt.exe"/>
- <propertyname="aidl"value="${sdk-platform-tools}/aidl.exe"/>
- <propertyname="dx"value="${sdk-platform-tools}/dx.bat"/>
- <propertyname="apkbuilder"value="${sdk-tools}/apkbuilder.bat"/>
- <propertyname="jarsigner"value="${env.JAVA_HOME}/bin/jarsigner"/>
- <!--编译需要的jar;如果项目使用到地图服务则需要maps.jar-->
- <propertyname="android-jar"value="${sdk-platform-folder}/android.jar"/>
- <!--编译aidl文件所需的预处理框架文件framework.aidl-->
- <propertyname="framework-aidl"value="${sdk-platform-folder}/framework.aidl"/>
- <!--生成R文件的相对目录-->
- <propertyname="outdir-gen"value="gen"/>
- <!--编译后的文件放置目录-->
- <propertyname="outdir-bin"value="out"/>
- <!--清单文件-->
- <propertyname="manifest-xml"value="AndroidManifest.xml"/>
- <!--源文件目录-->
- <propertyname="resource-dir"value="res"/>
- <propertyname="asset-dir"value="assets"/>
- <!--java源文件目录-->
- <propertyname="srcdir"value="src"/>
- <propertyname="srcdir-ospath"value="${basedir}/${srcdir}"/>
- <!--外部类库所在目录-->
- <propertyname="external-lib"value="lib"/>
- <propertyname="external-lib-ospath"value="${basedir}/${external-lib}"/>
- <!--生成class目录-->
- <propertyname="outdir-classes"value="${outdir-bin}"/>
- <propertyname="outdir-classes-ospath"value="${basedir}/${outdir-classes}"/>
- <!--classes.dex相关变量-->
- <propertyname="dex-file"value="classes.dex"/>
- <propertyname="dex-path"value="${outdir-bin}/${dex-file}"/>
- <propertyname="dex-ospath"value="${basedir}/${dex-path}"/>
- <!--经过aapt生成的资源包文件-->
- <propertyname="resources-package"value="${outdir-bin}/resources.ap_"/>
- <propertyname="resources-package-ospath"value="${basedir}/${resources-package}"/>
- <!--未认证apk包-->
- <propertyname="out-unsigned-package"value="${outdir-bin}/${appName}-unsigned.apk"/>
- <propertyname="out-unsigned-package-ospath"value="${basedir}/${out-unsigned-package}"/>
- <!--证书文件-->
- <propertyname="keystore-file"value="${basedir}/release.keystore"/>
- <!--已认证apk包-->
- <propertyname="out-signed-package"value="${outdir-bin}/${appName}.apk"/>
- <propertyname="out-signed-package-ospath"value="${basedir}/${out-signed-package}"/>
- <!--初始化工作-->
- <targetname="init">
- <echo>Initializingalloutputdirectories...</echo>
- <deletedir="${outdir-bin}"/>
- <mkdirdir="${outdir-bin}"/>
- <mkdirdir="${outdir-classes}"/>
- </target>
- <!--根据工程中的资源文件生成R.java文件-->
- <targetname="gen-R"depends="init">
- <echo>GeneratingR.javafromtheresources...</echo>
- <!--<execexecutable="${aapt}"failonerror="true">
- <argvalue="package"/>
- <argvalue="-f"/>
- <argvalue="-m"/>
- <argvalue="-J"/>
- <argvalue="${outdir-gen}"/>
- <argvalue="-S"/>
- <argvalue="${resource-dir}"/>
- <argvalue="-M"/>
- <argvalue="${manifest-xml}"/>
- <argvalue="-I"/>
- <argvalue="${android-jar}"/>
- </exec>-->
- <execexecutable="${aapt}"failonerror="true">
- <argvalue="package"/>
- <argvalue="-m"/>
- <argvalue="--auto-add-overlay"/>
- <argvalue="-J"/>
- <argvalue="${outdir-gen}"/>
- <argvalue="-M"/>
- <argvalue="${manifest-xml}"/>
- <argvalue="-S"/>
- <argvalue="${resource-dir}"/>
- <argvalue="-S"/>
- <argvalue="${library-dir}/${resource-dir}"/>
- <argvalue="--extra-packages"/>
- <argvalue="com.mobcent.share.android"/>
- <argvalue="-A"/>
- <argvalue="${asset-dir}"/>
- <argvalue="-I"/>
- <argvalue="${android-jar}"/>
- </exec>
- </target>
- <!--编译aidl文件-->
- <targetname="aidl"depends="gen-R">
- <echo>Compiling.aidlintojavafiles...</echo>
- <applyexecutable="${aidl}"failonerror="true">
- <!--指定预处理文件-->
- <argvalue="-p${framework-aidl}"/>
- <!--aidl声明的目录-->
- <argvalue="-I${srcdir}"/>
- <!--目标文件目录-->
- <argvalue="-o${outdir-gen}"/>
- <!--指定哪些文件需要编译-->
- <filesetdir="${srcdir}">
- <includename="**/*.aidl"/>
- </fileset>
- </apply>
- </target>
- <!--将工程中的java源文件编译成class文件-->
- <targetname="compile"depends="aidl">
- <echo>Compilingjavasourcecode...</echo>
- <javacencoding="utf-8"target="1.6"destdir="${outdir-classes}"bootclasspath="${android-jar}">
- <srcpath="src"/>
- <srcpath="gen"/>
- <srcpath="${library-dir}/src"/>
- <classpath>
- <filesetdir="${external-lib}"includes="*.jar"/>
- <filesetdir="${library-dir}/libs"includes="*.jar"/>
- <filelist>
- <filename="${android-maps-jar}"/>
- </filelist>
- </classpath>
- </javac>
- </target>
- <!--将.class文件转化成.dex文件-->
- <targetname="dex"depends="compile">
- <echo>Convertingcompiledfilesandexternallibrariesintoa.dex
- file...
- </echo>
- <execexecutable="${dx}"failonerror="true">
- <argvalue="--dex"/>
- <!--输出文件-->
- <argvalue="--output=${dex-ospath}"/>
- <!--要生成.dex文件的源classes和libraries-->
- <argvalue="${outdir-classes-ospath}"/>
- <argvalue="${external-lib-ospath}"/>
- <argvalue="${library-dir}/libs"/>
- </exec>
- </target>
- <!--将资源文件放进输出目录-->
- <!--在这截断-->
- <targetname="package-res-and-assets"depends="dex">
- <echo>Packagingresourcesandassets...</echo>
- <execexecutable="${aapt}"failonerror="true">
- <argvalue="package"/>
- <argvalue="-f"/>
- <argvalue="-M"/>
- <argvalue="${manifest-xml}"/>
- <argvalue="-S"/>
- <argvalue="${resource-dir}"/>
- <argvalue="-A"/>
- <argvalue="${asset-dir}"/>
- <argvalue="-S"/>
- <argvalue="${library-dir}/${resource-dir}"/>
- <argvalue="-A"/>
- <argvalue="${library-dir}/${asset-dir}"/>
- <argvalue="-I"/>
- <argvalue="${android-jar}"/>
- <argvalue="-F"/>
- <argvalue="${resources-package}"/>
- <argvalue="--auto-add-overlay"/>
- </exec>
- </target>
- <!--打包成未签证的apk-->
- <targetname="package"depends="dex,package-res-and-assets">
- <echo>Packagingunsignedapkforrelease...</echo>
- <execexecutable="${apkbuilder}"failonerror="true">
- <argvalue="${out-unsigned-package-ospath}"/>
- <argvalue="-u"/>
- <argvalue="-z"/>
- <argvalue="${resources-package-ospath}"/>
- <argvalue="-f"/>
- <argvalue="${dex-ospath}"/>
- <argvalue="-rf"/>
- <argvalue="${srcdir-ospath}"/>
- <argvalue="-nf"/>
- <argvalue="${library-dir}/libs"/>
- </exec>
- <echo>Itwillneedtobesignedwithjarsignerbeforebeingpublished.
- </echo>
- </target>
- <!--对apk进行签证-->
- <targetname="jarsigner"depends="package">
- <echo>Packagingsignedapkforrelease...</echo>
- <execexecutable="${jarsigner}"failonerror="true">
- <argvalue="-keystore"/>
- <argvalue="${keystore-file}"/>
- <argvalue="-storepass"/>
- <argvalue=""/>
- <argvalue="-keypass"/>
- <argvalue=""/>
- <argvalue="-signedjar"/>
- <argvalue="${out-signed-package-ospath}"/>
- <argvalue="${out-unsigned-package-ospath}"/>
- <!--不要忘了证书的别名-->
- <argvalue=""/>
- </exec>
- </target>
- <!--发布-->
- <targetname="release"depends="jarsigner">
- <!--删除未签证apk-->
- <deletefile="${out-unsigned-package-ospath}"/>
- <echo>APKisreleased.path:${out-signed-package-ospath}</echo>
- </target>
- </project>
Android官方提供的打包脚本: 1400多行,我加了中文注释,希望能看懂。
- <?xmlversion="1.0"encoding="UTF-8"?>
- <projectname="pet_dog_base_forum"default="release">
- <!--自己需要添加的属性-->
- <propertyname="sdk.dir"value="C:/ProgramFiles/android-sdk_r15-windows/android-sdk-windows"/>
- <!--导入project.properties文件,设置了编译的target和相关的library工程-->
- <propertyfile="project.properties"/>
- <!--导入build.properties文件,设置了android的目录和key-->
- <propertyfile="ant.properties"/>
- <!--
- Thisbuildfileisimportedbytheprojectbuildfile.Itcontains
- allthetargetsandtasksnecessarytobuildAndroidprojects,bethey
- regularprojects,libraryprojects,ortestprojects.
- Atthebeginningofthefileisalistofpropertiesthatcanbeoverridden
- byaddingthemtoyourbuild.properties(propertiesareimmutable,sotheir
- firstdefinitionsticksandisneverchanged).
- Follows:
- -customtaskdefinitions,
- -moreproperties(donotoverridethoseunlessthewholebuildsystemismodified).
- -macrosusedthroughoutthebuild,
- -basebuildtargets,
- -debug-specificbuildtargets,
- -release-specificbuildtargets,
- -instrument-specificbuildtargets,
- -testproject-specificbuildtargets,
- -installtargets,
- -helptarget
- 步骤如下:
- ——自定义task
- ——设置相关属性
- ——全局的使用整个构建
- ——基本bulid的targets
- ——debug使用的targets
- ——release使用的targets
- ——特定仪器使用的targets
- ——测试使用的targets
- ——安装的targets
- ——帮助的targets
- -->
- <!--**********OverrideableProperties**********-->
- <!--**********可重写的属性**********-->
- <!--Youcanoverridethesevaluesinyourbuild.xmlorbuild.properties.
- Overridinganyotherpropertiesmayresultinbrokenbuild.-->
- <!--你可以覆盖build.xml或者build.properties文件中的任何属性,覆盖任何一个属性,都可能导致build出错,慎用-->
- <!--Tellsadbwhichdevicetotarget.Youcanchangethisfromthecommandline
- byinvoking"ant-Dadb.device.arg=-d"fordevice"ant-Dadb.device.arg=-e"for
- theemulator.-->
- <!--设置链接的机器,
- ant-Dadb.device.arg=-d使用链接当前的设备
- ant-Dadb.device.arg=-e使用模拟器
- -->
- <propertyname="adb.device.arg"value=""/>
- <!--filesetexcludepatterns(spaceseparated)toprevent
- filesinsidesrc/frombeingpackaged.-->
- <!--设置改属性可以排除编译一部分代码
- -->
- <propertyname="android.package.excludes"value=""/>
- <!--setsomepropertiesusedforfiltering/override.Ifthoseweren'tdefined
- before,thenthiswillcreatethemwithemptyvalues,whicharethenignored
- bythecustomtasksreceivingthem.-->
- <!--
- version.code,version.name可以替換AndroidManifest.xml中的android:versionCode和android:versionName
- -->
- <propertyname="version.code"value="11"/>
- <propertyname="version.name"value="111"/>
- <propertyname="aapt.resource.filter"value=""/>
- <!--compilationoptions-->
- <propertyname="java.encoding"value="UTF-8"/>
- <propertyname="java.target"value="1.6"/>
- <propertyname="java.source"value="1.6"/>
- <!--Verbosity-->
- <propertyname="verbose"value="false"/>
- <!--**********CustomTasks**********-->
- <!--**********自定义Tasks**********-->
- <!--导入自定义Task是需要的文件-->
- <pathid="android.antlibs">
- <pathelementpath="${sdk.dir}/tools/lib/anttasks.jar"/>
- </path>
- <!--Customtasks-->
- <taskdefname="setup"classname="com.android.ant.NewSetupTask"classpathref="android.antlibs"/>
- <taskdefname="aapt"classname="com.android.ant.AaptExecTask"classpathref="android.antlibs"/>
- <taskdefname="aidl"classname="com.android.ant.AidlExecTask"classpathref="android.antlibs"/>
- <taskdefname="renderscript"classname="com.android.ant.RenderScriptTask"classpathref="android.antlibs"/>
- <taskdefname="dex"classname="com.android.ant.DexExecTask"classpathref="android.antlibs"/>
- <taskdefname="apkbuilder"classname="com.android.ant.ApkBuilderTask"classpathref="android.antlibs"/>
- <taskdefname="zipalign"classname="com.android.ant.ZipAlignTask"classpathref="android.antlibs"/>
- <taskdefname="xpath"classname="com.android.ant.XPathTask"classpathref="android.antlibs"/>
- <taskdefname="if"classname="com.android.ant.IfElseTask"classpathref="android.antlibs"/>
- <!--Emmaconfiguration
- EMMA是一种快速的,基于字节码指令的Java代码覆盖工具。
- -->
- <propertyname="emma.dir"value="${sdk.dir}/tools/lib"/>
- <pathid="emma.lib">
- <pathelementlocation="${emma.dir}/emma.jar"/>
- <pathelementlocation="${emma.dir}/emma_ant.jar"/>
- </path>
- <taskdefresource="emma_ant.properties"classpathref="emma.lib"/>
- <!--Endofemmaconfiguration-->
- <!--**********OtherProperties**********-->
- <!--overridingthesepropertiesmaybreakthebuild
- unlessthewholefileisupdated-->
- <!--输入文件-->
- <propertyname="source.dir"value="src"/>
- <propertyname="source.absolute.dir"location="${source.dir}"/>
- <propertyname="gen.absolute.dir"location="gen"/>
- <propertyname="resource.absolute.dir"location="res"/>
- <propertyname="asset.absolute.dir"location="assets"/>
- <propertyname="jar.libs.dir"value="libs"/>
- <propertyname="jar.libs.absolute.dir"location="${jar.libs.dir}"/>
- <propertyname="native.libs.absolute.dir"location="libs"/>
- <!--输出文件-->
- <propertyname="out.dir"value="bin"/>
- <propertyname="out.absolute.dir"location="${out.dir}"/>
- <propertyname="out.classes.absolute.dir"location="${out.dir}/classes"/>
- <propertyname="out.res.absolute.dir"location="${out.dir}/res"/>
- <!--toolslocation编译所需要用到的工具-->
- <propertyname="android.tools.dir"location="${sdk.dir}/tools"/>
- <propertyname="android.platform.tools.dir"location="${sdk.dir}/platform-tools"/>
- <conditionproperty="exe"value=".exe"else="">
- <osfamily="windows"/>
- </condition>
- <conditionproperty="bat"value=".bat"else="">
- <osfamily="windows"/>
- </condition>
- <propertyname="adb"location="${android.platform.tools.dir}/adb${exe}"/>
- <propertyname="zipalign"location="${android.tools.dir}/zipalign${exe}"/>
- <propertyname="aidl"location="${android.platform.tools.dir}/aidl${exe}"/>
- <propertyname="aapt"location="${android.platform.tools.dir}/aapt${exe}"/>
- <propertyname="dx"location="${android.platform.tools.dir}/dx${bat}"/>
- <!--renderscriptlocationissetbyNewSetupTasksincewehaveachoiceof
- severalexecutablesbasedonminSdkVersion-->
- <!--Intermediatefiles中间文件-->
- <propertyname="dex.file.name"value="classes.dex"/>
- <propertyname="intermediate.dex.file"location="${out.absolute.dir}/${dex.file.name}"/>
- <propertyname="resource.package.file.name"value="${ant.project.name}.ap_"/>
- <!--Buildpropertyfilebuild的属性文件-->
- <propertyname="out.build.prop.file"location="${out.absolute.dir}/build.prop"/>
- <!--Thisisneededbyemmaasitusesmultilevelverbosityinsteadofsimple'true'or'false'
- Theproperty'verbosity'isnotuserconfigurableanddependsexclusivelyon'verbose'
- value.
- 这是需要通过艾玛,因为它使用多级verbosity不是简单的“true”或“false”。属性“冗长”不是用户可配置的,只取决于verbose”值。
- -->
- <conditionproperty="verbosity"value="verbose"else="quiet">
- <istruevalue="${verbose}"/>
- </condition>
- <!--propertiesforsigninginreleasemode-->
- <!--签名所需要的文件-->
- <conditionproperty="has.keystore">
- <and>
- <issetproperty="key.store"/>
- <lengthstring="${key.store}"when="greater"length="0"/>
- <issetproperty="key.alias"/>
- </and>
- </condition>
- <conditionproperty="has.password">
- <and>
- <issetproperty="has.keystore"/>
- <issetproperty="key.store.password"/>
- <issetproperty="key.alias.password"/>
- </and>
- </condition>
- <!--propertiesforpackaging-->
- <propertyname="build.packaging.nocrunch"value="true"/>
- <!--**********Macros**********-->
- <!--**********宏定义**********-->
- <!--macrotodoataskonifproject.is.libraryisfalse.
- elseTextattributeisdisplayedotherwise-->
- <!--定义了没有关联library工程时,将会打印elseText-->
- <macrodefname="do-only-if-not-library">
- <attributename="elseText"/>
- <elementname="task-to-do"implicit="yes"/>
- <sequential>
- <ifcondition="${project.is.library}">
- <else>
- <task-to-do/>
- </else>
- <then>
- <echo>@{elseText}</echo>
- </then>
- </if>
- </sequential>
- </macrodef>
- <!--macrotodoataskonifmanifest.hasCodeistrue.
- elseTextattributeisdisplayedotherwise-->
- <macrodefname="do-only-if-manifest-hasCode">
- <attributename="elseText"default=""/>
- <elementname="task-to-do"implicit="yes"/>
- <sequential>
- <ifcondition="${manifest.hasCode}">
- <then>
- <task-to-do/>
- </then>
- <else>
- <if>
- <condition>
- <lengthstring="@{elseText}"trim="true"when="greater"length="0"/>
- </condition>
- <then>
- <echo>@{elseText}</echo>
- </then>
- </if>
- </else>
- </if>
- </sequential>
- </macrodef>
- <!--Configurablemacro,whichallowstopassasparametersoutputdirectory,
- outputdexfilenameandexternallibrariestodex(optional)
- 配置宏,允许通过参数设置输出的目录,dex文件和dex额外的libraries
- -->
- <macrodefname="dex-helper">
- <elementname="external-libs"optional="yes"/>
- <attributename="nolocals"default="false"/>
- <sequential>
- <!--setstheprimaryinputfordex.Ifapre-dextasksetsitto
- somethingelsethishasnoeffect-->
- <propertyname="out.dex.input.absolute.dir"value="${out.classes.absolute.dir}"/>
- <!--setthesecondarydxinput:theproject(andlibrary)jarfiles
- Ifapre-dextasksetsittosomethingelsethishasnoeffect-->
- <if>
- <condition>
- <isreferencerefid="out.dex.jar.input.ref"/>
- </condition>
- <else>
- <pathid="out.dex.jar.input.ref">
- <pathrefid="jar.libs.ref"/>
- </path>
- </else>
- </if>
- <dexexecutable="${dx}"output="${intermediate.dex.file}"nolocals="@{nolocals}"verbose="${verbose}"previousBuildType="${build.last.target}"buildType="${build.target}">
- <pathpath="${out.dex.input.absolute.dir}"/>
- <pathrefid="out.dex.jar.input.ref"/>
- <external-libs/>
- </dex>
- </sequential>
- </macrodef>
- <!--ThisismacrothatenablepassingvariablelistofexternaljarfilestoApkBuilder
- 设置ApkBuilder是额外的jar文件
- 默认把工程下libs中的jar文件打到APK里
- Exampleofuse:
- <package-helper>
- <extra-jars>
- <jarfolderpath="my_jars"/>
- <jarfilepath="foo/bar.jar"/>
- <jarfolderpath="your_jars"/>
- </extra-jars>
- </package-helper>-->
- <macrodefname="package-helper">
- <elementname="extra-jars"optional="yes"/>
- <sequential>
- <apkbuilderoutfolder="${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}">
- <dexpath="${intermediate.dex.file}"/>
- <sourcefolderpath="${source.absolute.dir}"/>
- <jarfilerefid="jar.libs.ref"/>
- <nativefolderpath="${native.libs.absolute.dir}"/>
- <nativefolderrefid="project.libraries.libs"/>
- <extra-jars/>
- </apkbuilder>
- </sequential>
- </macrodef>
- <!--Thisismacrowhichzipalignsin.packageandoutputsittoout.package.Usedbytargets
- debug,-debug-with-emmaandrelease.
- 通过zipaligns对APK进行优化
- -->
- <macrodefname="zipalign-helper">
- <attributename="in.package"/>
- <attributename="out.package"/>
- <sequential>
- <zipalignexecutable="${zipalign}"input="@{in.package}"output="@{out.package}"verbose="${verbose}"/>
- </sequential>
- </macrodef>
- <macrodefname="run-tests-helper">
- <attributename="emma.enabled"default="false"/>
- <elementname="extra-instrument-args"optional="yes"/>
- <sequential>
- <echo>Runningtests...</echo>
- <execexecutable="${adb}"failonerror="true">
- <argline="${adb.device.arg}"/>
- <argvalue="shell"/>
- <argvalue="am"/>
- <argvalue="instrument"/>
- <argvalue="-w"/>
- <argvalue="-e"/>
- <argvalue="coverage"/>
- <argvalue="@{emma.enabled}"/>
- <extra-instrument-args/>
- <argvalue="${manifest.package}/${test.runner}"/>
- </exec>
- </sequential>
- </macrodef>
- <macrodefname="record-build-key">
- <attributename="key"default="false"/>
- <attributename="value"default="false"/>
- <sequential>
- <propertyfilefile="${out.build.prop.file}"comment="Lastbuildtype">
- <entrykey="@{key}"value="@{value}"/>
- </propertyfile>
- </sequential>
- </macrodef>
- <macrodefname="record-build-info">
- <sequential>
- <record-build-keykey="build.last.target"value="${build.target}"/>
- <record-build-keykey="build.last.is.instrumented"value="${build.is.instrumented}"/>
- <record-build-keykey="build.last.is.packaging.debug"value="${build.is.packaging.debug}"/>
- <record-build-keykey="build.last.is.signing.debug"value="${build.is.signing.debug}"/>
- </sequential>
- </macrodef>
- <macrodefname="uninstall-helper">
- <attributename="app.package"default="false"/>
- <sequential>
- <echo>[email protected]{app.package}fromthedefaultemulatorordevice...</echo>
- <execexecutable="${adb}"failonerror="true">
- <argline="${adb.device.arg}"/>
- <argvalue="uninstall"/>
- <argvalue="@{app.package}"/>
- </exec>
- </sequential>
- </macrodef>
- <!--**********BuildTargets**********-->
- <!--thistargetsimplyforcerunning-setupmaking
- theprojectinfoberead.Tobeusedas
- antallclean
- tocleanthemainprojectaswellasthelibrariesandtestedproject
- 运行-setup,在此之前必须运行clean,
- -->
- <targetname="all"depends="-setup"/>
- <!--cleantarget-->
- <targetname="clean"description="Removesoutputfilescreatedbyothertargets.">
- <deletedir="${out.absolute.dir}"verbose="${verbose}"/>
- <deletedir="${gen.absolute.dir}"verbose="${verbose}"/>
- <!--ifweknowaboutatestedprojectorlibraries,wecleanthemtoo.This
- willonlyworkifthetarget'all'wascalledfirst-->
- <ifcondition="${project.is.test}">
- <then>
- <propertyname="tested.project.absolute.dir"location="${tested.project.dir}"/>
- <subantfailonerror="true">
- <filesetdir="${tested.project.absolute.dir}"includes="build.xml"/>
- <targetname="all"/>
- <targetname="clean"/>
- </subant>
- </then>
- </if>
- <if>
- <condition>
- <isreferencerefid="project.libraries"/>
- </condition>
- <then>
- <!--有libraries关联工程的时候,调用libraries工程中build.xml-->
- <subantbuildpathref="project.libraries"antfile="build.xml"failonerror="true">
- <targetname="all"/>
- <targetname="clean"/>
- </subant>
- </then>
- </if>
- </target>
- <!--genericsetup初始化-->
- <targetname="-setup">
- <if>
- <condition>
- <not>
- <issetproperty="setup.done"/>
- </not>
- </condition>
- <then>
- <propertyname="setup.done"value="true"/>
- <echo>Gatheringinfofor${ant.project.name}...</echo>
- <!--loadprojectproperties,resolveAndroidtarget,librarydependencies
- andsetsomepropertieswiththeresults.
- Allpropertynamesarepassedasparametersendingin-Out
- 加载projectproperties,设置Androidtarget,依赖的library工程和一些其他的属性
- -->
- <setupprojectTypeOut="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"/>
- <!--setsafewbooleanbasedonandroid.project.type
- tomaketheiftaskeasier-->
- <conditionproperty="project.is.library"else="false">
- <equalsarg1="${android.project.type}"arg2="library"/>
- </condition>
- <conditionproperty="project.is.test"else="false">
- <equalsarg1="${android.project.type}"arg2="test"/>
- </condition>
- <!--Ifatestproject,resolveabsolutepathtotestedproject.-->
- <ifcondition="${project.is.test}">
- <then>
- <propertyname="tested.project.absolute.dir"location="${tested.project.dir}"/>
- </then>
- </if>
- </then>
- </if>
- </target>
- <!--Prebuildsetup
- 预编译
- -->
- <targetname="-build-setup"depends="-setup">
- <!--readthepreviousbuildmode-->
- <propertyfile="${out.build.prop.file}"/>
- <!--ifemptythepropwon'tbeset,sosetittothecurrenttarget
- toprovideadefaultvalueequaltothecurrentbuild-->
- <propertyname="build.last.target"value="${build.target}"/>
- <!--alsosetthedefaultvalueforwhetherthebuildisinstrumented-->
- <propertyname="build.last.is.instrumented"value="${build.is.instrumented}"/>
- <propertyname="build.last.is.packaging.debug"value="${build.is.packaging.debug}"/>
- <propertyname="build.last.is.signing.debug"value="${build.is.signing.debug}"/>
- <!--compilethelibrariesifany
- 编译libraries
- -->
- <if>
- <condition>
- <isreferencerefid="project.libraries"/>
- </condition>
- <then>
- <echo>BuildingLibraries</echo>
- <subantbuildpathref="project.libraries"antfile="build.xml"target="${build.target}"failonerror="true"/>
- <echo>
- </echo>
- <echo>############################################</echo>
- <echo>****Backtoproject${ant.project.name}****</echo>
- <echo>############################################</echo>
- </then>
- </if>
- <!--compilethemainprojectifthisisatestproject
- 编译主工程,如果这是测试工程
- -->
- <ifcondition="${project.is.test}">
- <then>
- <!--figureoutwhichtargetmustbeusedtobuildthetestedproject.
- Ifemmaisenabled,thenuse'instrument'otherwise,use'debug'-->
- <conditionproperty="tested.project.target"value="instrument"else="debug">
- <issetproperty="emma.enabled"/>
- </condition>
- <echo>Buildingtestedprojectat${tested.project.absolute.dir}</echo>
- <subanttarget="${tested.project.target}"failonerror="true">
- <filesetdir="${tested.project.absolute.dir}"includes="build.xml"/>
- </subant>
- <echo>
- </echo>
- <echo>############################################</echo>
- <echo>****Backtoproject${ant.project.name}****</echo>
- <echo>############################################</echo>
- </then>
- </if>
- <!--ValueofthehasCodeattribute(Applicationnode)extractedfrommanifestfile-->
- <xpathinput="AndroidManifest.xml"expression="/manifest/application/@android:hasCode"output="manifest.hasCode"default="true"/>
- <!--createapathwithallthejarfiles,fromthemainprojectandthe
- libraries
- 创建一个path,关联所有的jar文件。每个工程下的libs下的jar文件
- -->
- <pathid="jar.libs.ref">
- <filesetdir="${jar.libs.absolute.dir}"includes="*.jar"/>
- <pathrefid="project.libraries.jars"/>
- </path>
- <!--specialcaseforinstrumented:ifthepreviousbuildwas
- instrumentedbutnotthisone,clearoutthecompiledcode
- 特殊情况被打断,清除已编译的代码
- -->
- <if>
- <condition>
- <and>
- <istruevalue="${build.last.is.instrumented}"/>
- <isfalsevalue="${build.is.instrumented}"/>
- </and>
- </condition>
- <then>
- <echo>Switchingfrominstrumentedtonon-instrumentedbuild.</echo>
- <echo>Deletingpreviouscompilationoutput:</echo>
- <deletedir="${out.classes.absolute.dir}"verbose="${verbose}"/>
- </then>
- </if>
- <echo>Creatingoutputdirectoriesifneeded...</echo>
- <mkdirdir="${resource.absolute.dir}"/>
- <mkdirdir="${jar.libs.absolute.dir}"/>
- <mkdirdir="${out.absolute.dir}"/>
- <mkdirdir="${out.res.absolute.dir}"/>
- <do-only-if-manifest-hasCode>
- <mkdirdir="${gen.absolute.dir}"/>
- <mkdirdir="${out.classes.absolute.dir}"/>
- </do-only-if-manifest-hasCode>
- </target>
- <!--emptydefaultpre-buildtarget.Createasimilartargetin
- yourbuild.xmlandit'llbecalledinsteadofthisone.-->
- <targetname="-pre-build"/>
- <!--CodeGeneration:compileresources(aapt->R.java),aidl,renderscript
- 通过appt生成R.jar文件
- -->
- <targetname="-code-gen">
- <do-only-if-manifest-hasCodeelseText="hasCode=false.Skippingaidl/renderscript/R.java">
- <echo>----------</echo>
- <echo>Handlingaidlfiles...</echo>
- <aidlexecutable="${aidl}"framework="${android.aidl}"genFolder="${gen.absolute.dir}">
- <sourcepath="${source.absolute.dir}"/>
- </aidl>
- <!--renderscriptgeneratesresourcessoitmustbecalledbeforeaapt-->
- <echo>----------</echo>
- <echo>HandlingRenderScriptfiles...</echo>
- <renderscriptexecutable="${renderscript}"framework="${android.rs}"genFolder="${gen.absolute.dir}"resFolder="${resource.absolute.dir}/raw"targetApi="${target.api}">
- <sourcepath="${source.absolute.dir}"/>
- </renderscript>
- <echo>----------</echo>
- <echo>HandlingResources...</echo>
- <aaptexecutable="${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">
- <respath="${resource.absolute.dir}"/>
- </aapt>
- </do-only-if-manifest-hasCode>
- </target>
- <!--emptydefaultpre-compiletarget.Createasimilartargetin
- yourbuild.xmlandit'llbecalledinsteadofthisone.-->
- <targetname="-pre-compile"/>
- <!--Compilesthisproject's.javafilesinto.classfiles.
- 编译
- -->
- <targetname="-compile"depends="-build-setup,-pre-build,-code-gen,-pre-compile">
- <do-only-if-manifest-hasCodeelseText="hasCode=false.Skipping...">
- <!--Ifandroidrulesareusedforatestproject,itsclasspathshouldinclude
- testedproject'slocation
- 如果是测试工程,classpath应该包括test的位置
- -->
- <conditionproperty="extensible.classpath"value="${tested.project.absolute.dir}/bin/classes"else=".">
- <issetproperty="tested.project.absolute.dir"/>
- </condition>
- <conditionproperty="extensible.libs.classpath"value="${tested.project.absolute.dir}/${jar.libs.dir}"else="${jar.libs.dir}">
- <issetproperty="tested.project.absolute.dir"/>
- </condition>
- <javacencoding="${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">
- <srcpath="${source.absolute.dir}"/>
- <srcpath="${gen.absolute.dir}"/>
- <classpath>
- <filesetdir="${extensible.libs.classpath}"includes="*.jar"/>
- </classpath>
- </javac>
- <!--iftheprojectisalibrarythenwegenerateajarfile
- 如果工程是library工程,则生成jar文件
- -->
- <ifcondition="${project.is.library}">
- <then>
- <echo>Creatinglibraryoutputjarfile...</echo>
- <propertyname="out.library.jar.file"location="${out.absolute.dir}/classes.jar"/>
- <if>
- <condition>
- <lengthstring="${android.package.excludes}"trim="true"when="greater"length="0"/>
- </condition>
- <then>
- <echo>Customjarpackagingexclusion:${android.package.excludes}</echo>
- </then>
- </if>
- <jardestfile="${out.library.jar.file}">
- <filesetdir="${out.classes.absolute.dir}"excludes="**/R.class**/R$*.class"/>
- <filesetdir="${source.absolute.dir}"excludes="**/*.java${android.package.excludes}"/>
- </jar>
- </then>
- </if>
- <!--iftheprojectisinstrumented,intrumenttheclasses
- 如果工程被打断,插入相关的class
- -->
- <ifcondition="${build.is.instrumented}">
- <then>
- <echo>Instrumentingclassesfrom${out.absolute.dir}/classes...</echo>
- <!--Itonlyinstrumentsclassfiles,notanyexternallibs-->
- <emmaenabled="true">
- <instrverbosity="${verbosity}"mode="overwrite"instrpath="${out.absolute.dir}/classes"outdir="${out.absolute.dir}/classes">
- </instr>
- <!--TODO:exclusionfiltersonR*.classandallowingcustomexclusionfrom
- userdefinedfile-->
- </emma>
- </then>
- </if>
- </do-only-if-manifest-hasCode>
- </target>
- <!--emptydefaultpost-compiletarget.Createasimilartargetin
- yourbuild.xmlandit'llbecalledinsteadofthisone.-->
- <targetname="-post-compile"/>
- <!--Obfuscatetarget
- Thisisonlyactiveinreleasebuildswhenproguard.configisdefined
- indefault.properties.
- ToreplaceProguardwithadifferentobfuscationengine:
- Overridethefollowingtargetsinyourbuild.xml,beforethecallto<setup>
- -release-obfuscation-check
- Checkwhetherobfuscationshouldhappen,andputtheresultinaproperty.
- -debug-obfuscation-check
- Obfuscationshouldnothappen.Setthesamepropertytofalse.
- -obfuscate
- checkifthepropertysetin-debug/release-obfuscation-checkissettotrue.
- Iftrue:
- Performobfuscation
- Setpropertyout.dex.input.absolute.dirtobetheoutputoftheobfuscation
- 混淆代码
- -->
- <targetname="-obfuscate">
- <ifcondition="${proguard.enabled}">
- <then>
- <propertyname="obfuscate.absolute.dir"location="${out.absolute.dir}/proguard"/>
- <propertyname="preobfuscate.jar.file"value="${obfuscate.absolute.dir}/original.jar"/>
- <propertyname="obfuscated.jar.file"value="${obfuscate.absolute.dir}/obfuscated.jar"/>
- <!--inputfordexwillbeproguard'soutput-->
- <propertyname="out.dex.input.absolute.dir"value="${obfuscated.jar.file}"/>
- <!--AddProguardTasks-->
- <propertyname="proguard.jar"location="${android.tools.dir}/proguard/lib/proguard.jar"/>
- <taskdefname="proguard"classname="proguard.ant.ProGuardTask"classpath="${proguard.jar}"/>
- <!--SettheandroidclasspathPathobjectintoasingleproperty.It'llbe
- allthejarfilesseparatedbyaplatformpath-separator.
- Eachpathmustbequotedifitcontainsspaces.
- -->
- <pathconvertproperty="android.libraryjars"refid="android.target.classpath">
- <firstmatchmapper>
- <regexpmapperfrom='^([^]*)(.*)$$'to='"\1\2"'/>
- <identitymapper/>
- </firstmatchmapper>
- </pathconvert>
- <!--Buildapathobjectwithallthejarfilesthatmustbeobfuscated.
- Thisincludetheprojectcompiledsourcecodeandany3rdpartyjar
- files.-->
- <pathid="project.jars.ref">
- <pathelementlocation="${preobfuscate.jar.file}"/>
- <pathrefid="jar.libs.ref"/>
- </path>
- <!--SettheprojectjarfilesPathobjectintoasingleproperty.It'llbe
- allthejarfilesseparatedbyaplatformpath-separator.
- Eachpathmustbequotedifitcontainsspaces.
- -->
- <pathconvertproperty="project.jars"refid="project.jars.ref">
- <firstmatchmapper>
- <regexpmapperfrom='^([^]*)(.*)$$'to='"\1\2"'/>
- <identitymapper/>
- </firstmatchmapper>
- </pathconvert>
- <mkdirdir="${obfuscate.absolute.dir}"/>
- <deletefile="${preobfuscate.jar.file}"/>
- <deletefile="${obfuscated.jar.file}"/>
- <jarbasedir="${out.classes.absolute.dir}"destfile="${preobfuscate.jar.file}"/>
- <proguard>
- @${proguard.config}
- -injars${project.jars}
- -outjars"${obfuscated.jar.file}"
- -libraryjars${android.libraryjars}
- -dump"${obfuscate.absolute.dir}/dump.txt"
- -printseeds"${obfuscate.absolute.dir}/seeds.txt"
- -printusage"${obfuscate.absolute.dir}/usage.txt"
- -printmapping"${obfuscate.absolute.dir}/mapping.txt"
- </proguard>
- </then>
- </if>
- </target>
- <!--Convertsthisproject's.classfilesinto.dexfiles
- 将.class打包成.dex文件
- -->
- <targetname="-dex"depends="-compile,-post-compile,-obfuscate">
- <do-only-if-manifest-hasCodeelseText="hasCode=false.Skipping...">
- <!--onlyconverttodalvikbytecodeis*not*alibrary-->
- <do-only-if-not-libraryelseText="Libraryproject:donotconvertbytecode...">
- <!--specialcaseforinstrumentedbuilds:needtouseno-localsandneed
- topassintheemmajar.
- 特殊情况下,检测build,需要通过emma
- -->
- <ifcondition="${build.is.instrumented}">
- <then>
- <dex-helpernolocals="true">
- <external-libs>
- <filesetfile="${emma.dir}/emma_device.jar"/>
- </external-libs>
- </dex-helper>
- </then>
- <else>
- <dex-helper/>
- </else>
- </if>
- </do-only-if-not-library>
- </do-only-if-manifest-hasCode>
- </target>
- <!--Updatesthepre-processedPNGcache处理png图片-->
- <targetname="-crunch">
- <execexecutable="${aapt}"taskName="crunch">
- <argvalue="crunch"/>
- <argvalue="-v"/>
- <argvalue="-S"/>
- <argpath="${resource.absolute.dir}"/>
- <argvalue="-C"/>
- <argpath="${out.res.absolute.dir}"/>
- </exec>
- </target>
- <!--Putstheproject'sresourcesintotheoutputpackagefile
- Thisactuallycancreatemultipleresourcepackageincase
- Somecustomapkwithspecificconfigurationhavebeen
- declaredindefault.properties.
- 打包资源文件
- -->
- <targetname="-package-resources"depends="-crunch">
- <!--onlypackageresourcesif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:donotpackageresources...">
- <aaptexecutable="${aapt}"command="package"versioncode="${version.code}"versionname="${version.name}"debug="${build.is.packaging.debug}"manifest="AndroidManifest.xml"assets="${asset.absolute.dir}"androidjar="${android.jar}"apkfolder="${out.absolute.dir}"nocrunch="${build.packaging.nocrunch}"resourcefilename="${resource.package.file.name}"resourcefilter="${aapt.resource.filter}"projectLibrariesResName="project.libraries.res"projectLibrariesPackageName="project.libraries.package"previousBuildType="${build.last.target}"buildType="${build.target}">
- <respath="${out.res.absolute.dir}"/>
- <respath="${resource.absolute.dir}"/>
- <!--<nocompress/>forcesnocompressiononanyfilesinassetsorres/raw-->
- <!--<nocompressextension="xml"/>forcesnocompressiononspecificfileextensionsinassetsandres/raw-->
- </aapt>
- </do-only-if-not-library>
- </target>
- <!--Packagestheapplication.打包-->
- <targetname="-package"depends="-dex,-package-resources">
- <!--onlypackageapkif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:donotpackageapk...">
- <ifcondition="${build.is.instrumented}">
- <then>
- <package-helper>
- <extra-jars>
- <!--Injectedfromexternalfile-->
- <jarfilepath="${emma.dir}/emma_device.jar"/>
- </extra-jars>
- </package-helper>
- </then>
- <else>
- <package-helper/>
- </else>
- </if>
- </do-only-if-not-library>
- </target>
- <targetname="-set-mode-check">
- <failif="out.final.file"message="Cannotruntwodifferentmodesatthesametime.Ifyouarerunningmorethanonedebug/release/instrumenttypetargets,callthemfromdifferentAntcalls."/>
- </target>
- <!--**********Debugspecifictargets**********-->
- <!--设置debug-->
- <targetname="-set-debug-files"depends="-set-mode-check">
- <propertyname="out.packaged.file"location="${out.absolute.dir}/${ant.project.name}-debug-unaligned.apk"/>
- <propertyname="out.final.file"location="${out.absolute.dir}/${ant.project.name}-debug.apk"/>
- </target>
- <targetname="-set-debug-mode">
- <!--recordthecurrentbuildtarget-->
- <propertyname="build.target"value="debug"/>
- <propertyname="build.is.instrumented"value="false"/>
- <!--whetherthebuildisadebugbuild.alwaysset.-->
- <propertyname="build.is.packaging.debug"value="true"/>
- <!--signingmode:debug-->
- <propertyname="build.is.signing.debug"value="true"/>
- </target>
- <!--debug模式下,不使用混淆-->
- <targetname="-debug-obfuscation-check">
- <!--proguardisneverenabledindebugmode-->
- <propertyname="proguard.enabled"value="false"/>
- </target>
- <!--Buildsdebugoutputpackage-->
- <targetname="-do-debug"depends="-set-debug-mode,-debug-obfuscation-check,-package">
- <!--onlycreateapkif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:donotcreateapk...">
- <sequential>
- <zipalign-helperin.package="${out.packaged.file}"out.package="${out.final.file}"/>
- <echo>DebugPackage:${out.final.file}</echo>
- </sequential>
- </do-only-if-not-library>
- </target>
- <!--Buildsdebugoutputpackage-->
- <targetname="debug"depends="-set-debug-files,-do-debug"description="Buildstheapplicationandsignsitwithadebugkey.">
- <record-build-info/>
- </target>
- <!--**********Releasespecifictargets**********-->
- <!--发布的targets-->
- <!--calledthroughtarget'release'.Onlyexecutedifthekeystoreand
- keyaliasareknownbutnottheirpassword.
- 需要输入key.alias.password,key.store.password
- -->
- <targetname="-release-prompt-for-password"if="has.keystore"unless="has.password">
- <!--Getspasswords-->
- <inputmessage="Pleaseenterkeystorepassword(store:${key.store}):"addproperty="key.store.password"/>
- <inputmessage="Pleaseenterpasswordforalias'${key.alias}':"addproperty="key.alias.password"/>
- </target>
- <!--calledthroughtarget'release'.Onlyexecutedifthere'sno
- keystore/keyaliasset-->
- <targetname="-release-nosign"unless="has.keystore">
- <!--noreleasebuildsforlibraryproject-->
- <do-only-if-not-libraryelseText="">
- <sequential>
- <echo>Nokey.storeandkey.aliaspropertiesfoundinbuild.properties.</echo>
- <echo>Pleasesign${out.packaged.file}manually</echo>
- <echo>andrunzipalignfromtheAndroidSDKtools.</echo>
- </sequential>
- </do-only-if-not-library>
- <record-build-info/>
- </target>
- <!--检查是否混淆代码-->
- <targetname="-release-obfuscation-check">
- <conditionproperty="proguard.enabled"value="true"else="false">
- <and>
- <issetproperty="build.is.mode.release"/>
- <issetproperty="proguard.config"/>
- </and>
- </condition>
- <ifcondition="${proguard.enabled}">
- <then>
- <!--Secondarydxinput(jarfiles)isemptysinceallthe
- jarfileswillbeintheobfuscatedjar-->
- <pathid="out.dex.jar.input.ref"/>
- </then>
- </if>
- </target>
- <targetname="-set-release-mode"depends="-set-mode-check">
- <propertyname="out.packaged.file"location="${out.absolute.dir}/${ant.project.name}-release-unsigned.apk"/>
- <propertyname="out.final.file"location="${out.absolute.dir}/${ant.project.name}-release.apk"/>
- <!--recordthecurrentbuildtarget-->
- <propertyname="build.target"value="release"/>
- <propertyname="build.is.instrumented"value="false"/>
- <!--releasemodeisonlyvalidifthemanifestdoesnotexplicitly
- setdebuggabletotrue.defaultisfalse.-->
- <xpathinput="AndroidManifest.xml"expression="/manifest/application/@android:debuggable"output="build.is.packaging.debug"default="false"/>
- <!--signingmode:release-->
- <propertyname="build.is.signing.debug"value="false"/>
- <ifcondition="${build.is.packaging.debug}">
- <then>
- <echo>*************************************************</echo>
- <echo>****AndroidManifesthasdebuggable=true****</echo>
- <echo>****DoingDEBUGpackagingwithRELEASEkeys****</echo>
- <echo>*************************************************</echo>
- </then>
- <else>
- <!--propertyonlysetinreleasemode.
- Usefulforif/unlessattributesintargetnode
- whenusingAntbefore1.8-->
- <propertyname="build.is.mode.release"value="true"/>
- </else>
- </if>
- </target>
- <!--Thisruns-package-releaseand-release-nosignfirstandthenruns
- onlyifrelease-signistrue(setin-release-check,
- calledby-release-no-sign)-->
- <targetname="release"depends="-set-release-mode,-release-obfuscation-check,-package,-release-prompt-for-password,-release-nosign"if="has.keystore"description="Buildstheapplication.Thegeneratedapkfilemustbesignedbefore
- itispublished.">
- <!--onlycreateapkif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:donotcreateapk...">
- <sequential>
- <propertyname="out.unaligned.file"location="${out.absolute.dir}/${ant.project.name}-release-unaligned.apk"/>
- <!--SignstheAPK-->
- <echo>Signingfinalapk...</echo>
- <signjarjar="${out.packaged.file}"signedjar="${out.unaligned.file}"keystore="${key.store}"storepass="${key.store.password}"alias="${key.alias}"keypass="${key.alias.password}"verbose="${verbose}"/>
- <!--ZipalignstheAPK-->
- <zipalign-helperin.package="${out.unaligned.file}"out.package="${out.final.file}"/>
- <echo>ReleasePackage:${out.final.file}</echo>
- </sequential>
- </do-only-if-not-library>
- <record-build-info/>
- </target>
- <!--**********Instrumentedspecifictargets**********-->
- <!--需要插入的特殊targets-->
- <!--Thesetargetsarespecificfortheprojectundertestwhenit
- getscompiledbythetestprojectsinawaythatwillmakeit
- supportemmacodecoverage-->
- <targetname="-set-instrumented-mode"depends="-set-mode-check">
- <propertyname="out.packaged.file"location="${out.absolute.dir}/${ant.project.name}-instrumented-unaligned.apk"/>
- <propertyname="out.final.file"location="${out.absolute.dir}/${ant.project.name}-instrumented.apk"/>
- <!--whetherthebuildisaninstrumentedbuild.-->
- <propertyname="build.is.instrumented"value="true"/>
- </target>
- <!--Buildsinstrumentedoutputpackage-->
- <targetname="instrument"depends="-set-instrumented-mode,-do-debug"description="Buildsaninstrumentedpackaged.">
- <!--onlycreateapkif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:donotcreateapk...">
- <sequential>
- <zipalign-helperin.package="${out.packaged.file}"out.package="${out.final.file}"/>
- <echo>InstrumentedPackage:${out.final.file}</echo>
- </sequential>
- </do-only-if-not-library>
- <record-build-info/>
- </target>
- <!--**********Testprojectspecifictargets**********-->
- <!--测试工程特殊的targets-->
- <!--enablecodecoverage-->
- <targetname="emma">
- <propertyname="emma.enabled"value="true"/>
- </target>
- <!--failsiftheprojectisnotatestproject-->
- <targetname="-test-project-check">
- <!--can'tuseproject.is.testsincethesetuptargetisnotrun-->
- <if>
- <condition>
- <issetproperty="tested.project.dir"/>
- </condition>
- <else>
- <failmessage="Projectisnotatestproject."/>
- </else>
- </if>
- </target>
- <targetname="test"depends="-test-project-check"description="Runstestsfromthepackagedefinedintest.packageproperty">
- <propertyname="tested.project.absolute.dir"location="${tested.project.dir}"/>
- <propertyname="test.runner"value="android.test.InstrumentationTestRunner"/>
- <!--Applicationpackageofthetestedprojectextractedfromitsmanifestfile-->
- <xpathinput="${tested.project.absolute.dir}/AndroidManifest.xml"expression="/manifest/@package"output="tested.manifest.package"/>
- <xpathinput="AndroidManifest.xml"expression="/manifest/@package"output="manifest.package"/>
- <propertyname="emma.dump.file"value="/data/data/${tested.manifest.package}/coverage.ec"/>
- <ifcondition="${emma.enabled}">
- <then>
- <echo>WARNING:CodeCoverageiscurrentlyonlysupportedontheemulatorandrooteddevices.</echo>
- <run-tests-helperemma.enabled="true">
- <extra-instrument-args>
- <argvalue="-e"/>
- <argvalue="coverageFile"/>
- <argvalue="${emma.dump.file}"/>
- </extra-instrument-args>
- </run-tests-helper>
- <echo>Downloadingcoveragefileintoprojectdirectory...</echo>
- <execexecutable="${adb}"failonerror="true">
- <argline="${adb.device.arg}"/>
- <argvalue="pull"/>
- <argvalue="${emma.dump.file}"/>
- <argvalue="coverage.ec"/>
- </exec>
- <echo>Extractingcoveragereport...</echo>
- <emma>
- <reportsourcepath="${tested.project.absolute.dir}/${source.dir}"verbosity="${verbosity}">
- <!--TODO:report.dirorsomethinglikeshouldbeintroducedifnecessary-->
- <infilesetdir=".">
- <includename="coverage.ec"/>
- <includename="coverage.em"/>
- </infileset>
- <!--TODO:reportsinother,indicatedbyuserformats-->
- <htmloutfile="coverage.html"/>
- </report>
- </emma>
- <echo>Cleaninguptemporaryfiles...</echo>
- <deletefile="coverage.ec"/>
- <deletefile="coverage.em"/>
- <echo>Savingthereportfilein${basedir}/coverage/coverage.html</echo>
- </then>
- <else>
- <run-tests-helper/>
- </else>
- </if>
- </target>
- <!--**********Install/uninstallspecifictargets**********-->
- <!--安装和卸载-->
- <targetname="install"description="Installsthenewlybuildpackage.Mustbeusedinconjunctionwithabuildtarget
- (debug/release/instrument).Iftheapplicationwaspreviouslyinstalled,theapplication
- isreinstalledifthesignaturematches.">
- <!--onlydoinstallif*not*alibraryproject-->
- <do-only-if-not-libraryelseText="Libraryproject:nothingtoinstall!">
- <if>
- <condition>
- <issetproperty="out.final.file"/>
- </condition>
- <then>
- <if>
- <condition>
- <resourceexists>
- <filefile="${out.final.file}"/>
- </resourceexists>
- </condition>
- <then>
- <echo>Installing${out.final.file}ontodefaultemulatorordevice...</echo>
- <execexecutable="${adb}"failonerror="true">
- <argline="${adb.device.arg}"/>
- <argvalue="install"/>
- <argvalue="-r"/>
- <argpath="${out.final.file}"/>
- </exec>
- <!--nowinstallthetestedprojectifapplicable-->
- <!--can'tuseproject.is.testsincethesetuptargetmightnothaverun-->
- <if>
- <condition>
- <issetproperty="tested.project.dir"/>
- </condition>
- <then>
- <propertyname="tested.project.absolute.dir"location="${tested.project.dir}"/>
- <!--figureoutwhichtestedpackagetoinstallbasedonemma.enabled-->
- <conditionproperty="tested.project.install.target"value="installi"else="installd">
- <issetproperty="emma.enabled"/>
- </condition>
- <subanttarget="${tested.project.install.target}"failonerror="true">
- <filesetdir="${tested.project.absolute.dir}"includes="build.xml"/>
- </subant>
- </then>
- </if>
- </then>
- <else>
- <failmessage="File${out.final.file}doesnotexist."/>
- </else>
- </if>
- </then>
- <else>
- <echo>Installfilenotspecified.</echo>
- <echo>
- </echo>
- <echo>'antinstall'nowrequiresthebuildtargettobespecifiedaswell.</echo>
- <echo>
- </echo>
- <echo>
- </echo>
- <echo>antdebuginstall</echo>
- <echo>antreleaseinstall</echo>
- <echo>antinstrumentinstall</echo>
- <echo>Thiswillbuildthegivenpackageandinstallit.</echo>
- <echo>
- </echo>
- <echo>Alternatively,youcanuse</echo>
- <echo>antinstalld</echo>
- <echo>antinstallr</echo>
- <echo>antinstalli</echo>
- <echo>antinstallt</echo>
- <echo>toonlyinstallanexistingpackage(thiswillnotrebuildthepackage.)</echo>
- <fail/>
- </else>
- </if>
- </do-only-if-not-library>
- </target>
- <targetname="installd"depends="-set-debug-files,install"description="Installs(only)thedebugpackage."/>
- <targetname="installr"depends="-set-release-mode,install"description="Installs(only)thereleasepackage."/>
- <targetname="installi"depends="-set-instrumented-mode,install"description="Installs(only)theinstrumentedpackage."/>
- <targetname="installt"depends="-test-project-check,installd"description="Installs(only)thetestandtestedpackages."/>
- <!--Uninstallsthepackagefromthedefaultemulator/device-->
- <targetname="uninstall"description="Uninstallstheapplicationfromarunningemulatorordevice.">
- <!--Nameoftheapplicationpackageextractedfrommanifestfile-->
- <xpathinput="AndroidManifest.xml"expression="/manifest/@package"output="manifest.package"/>
- <if>
- <condition>
- <issetproperty="manifest.package"/>
- </condition>
- <then>
- <uninstall-helperapp.package="${manifest.package}"/>
- </then>
- <else>
- <echo>Couldnotfindapplicationpackageinmanifest.Cannotrun'adbuninstall'.</echo>
- </else>
- </if>
- <!--Nowuninstallthetestedproject,ifapplicable-->
- <!--can'tuseproject.is.testsincethesetuptargetmightnothaverun-->
- <if>
- <condition>
- <issetproperty="tested.project.dir"/>
- </condition>
- <then>
- <propertyname="tested.project.absolute.dir"location="${tested.project.dir}"/>
- <!--Applicationpackageofthetestedprojectextractedfromitsmanifestfile-->
- <xpathinput="${tested.project.absolute.dir}/AndroidManifest.xml"expression="/manifest/@package"output="tested.manifest.package"/>
- <if>
- <condition>
- <issetproperty="tested.manifest.package"/>
- </condition>
- <then>
- <uninstall-helperapp.package="${tested.manifest.package}"/>
- </then>
- <else>
- <echo>Couldnotfindtestedapplicationpackageinmanifest.Cannotrun'adbuninstall'.</echo>
- </else>
- </if>
- </then>
- </if>
- </target>
- <targetname="help">
- <!--displaysstartsatcol13
- |1380|-->
- <echo>AndroidAntBuild.Availabletargets:</echo>
- <echo>help:Displaysthishelp.</echo>
- <echo>clean:Removesoutputfilescreatedbyothertargets.</echo>
- <echo>The'all'targetcanbeusedtocleandependencies</echo>
- <echo>(testedprojectsandlibraries)atthesametime</echo>
- <echo>using:'antallclean'</echo>
- <echo>debug:Buildstheapplicationandsignsitwithadebugkey.</echo>
- <echo>release:Buildstheapplication.Thegeneratedapkfilemustbe</echo>
- <echo>signedbeforeitispublished.</echo>
- <echo>instrument:Buildsaninstrumentedpackageandsignsitwitha</echo>
- <echo>debugkey.</echo>
- <echo>test:Runsthetests.Projectmustbeatestprojectand</echo>
- <echo>musthavebeenbuilt.Typicalusagewouldbe:</echo>
- <echo>ant[emma]debuginstallttest</echo>
- <echo>emma:Transientlyenablescodecoverageforsubsequent</echo>
- <echo>targets.</echo>
- <echo>install:Installsthenewlybuildpackage.Musteitherbeused</echo>
- <echo>inconjunctionwithabuildtarget(debug/release/</echo>
- <echo>instrument)orwiththepropersuffixindicating</echo>
- <echo>whichpackagetoinstall(seebelow).</echo>
- <echo>Iftheapplicationwaspreviouslyinstalled,the</echo>
- <echo>applicationisreinstalledifthesignaturematches.</echo>
- <echo>installd:Installs(only)thedebugpackage.</echo>
- <echo>installr:Installs(only)thereleasepackage.</echo>
- <echo>installi:Installs(only)theinstrumentedpackage.</echo>
- <echo>installt:Installs(only)thetestandtestedpackages.</echo>
- <echo>uninstall:Uninstallstheapplicationfromarunningemulatoror</echo>
- <echo>device.</echo>
- </target>
- </project>