Android 自动 打包

Android 自动 打包(一)

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


<project name="xiyou_base_" default="deployableAllDevice"> 
<!-- proguard4的路径 --> 


<property name="proguard.home" value="D:/software/j2me/proguard4.5.1/proguard4.5.1"/> 
<!-- sdk的路径 --> 
<property name="sdk.dir" value="E:\dev\android-sdk-windows"/> 
<!-- 是否使用签名 --> 
<property name="has.keystore" value="true" /> 
<!-- 签名密码 --> 
<property name="has.password" value="true" /> 
<!--签名相关的key --> 
<property name="key.alias" value="key.keystore" /> 
<property name="key.store" value="key.keystore" /> 
<!-- 签名相关的密码 --> 
<property name="key.store.password" value="xxxx" /> 
<property name="key.alias.password" value="xxxx" /> 




<!-- 
default.properties 内容 
target=android-4 
proguard.config=proguard.cfg 
--> 


<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" /> 
<setup import="false" /> 


<!-- 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" />
  <!-- 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" />
  <property name="android.platform.tools.dir" location="${sdk.dir}/platform-tools" />
  <!-- Name of the application package extracted from manifest file -->
  <xpath input="AndroidManifest.xml" expression="/manifest/@package" output="manifest.package" />


<!-- Value of the hasCode attribute (Application node) extracted from manifest file -->
  <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:hasCode" output="manifest.hasCode" default="true" />
  <!-- 源文件及资源路径 -->
  <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="jar.libs.dir" value="libs" />
  <property name="jar.libs.absolute.dir" location="${jar.libs.dir}" />
  <!-- create a path with all the jar files, from the main project and the
  libraries -->
  <path id="jar.libs.ref">
  <fileset dir="${jar.libs.absolute.dir}" includes="*.jar" />
  <path refid="project.libraries.jars" />
  </path>
  <!-- Directory for the native libraries -->
  <property name="native.libs.dir" value="libs" />
  <property name="native.libs.absolute.dir" location="${native.libs.dir}" />
  <!-- 输出路径 -->
  <property name="out.dir" value="out" />
  <property name="out.absolute.dir" location="${out.dir}" />
  <property name="out.classes.dir" value="${out.absolute.dir}/classes" />
  <property name="out.classes.absolute.dir" location="${out.classes.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_" />  




Android 自动 打包(二)

<!-- 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}" />


  <property name="proguard.enabled" value="true" />


  <property name="android-jar" value="${sdk.dir}/platforms/${target}/android.jar" />


  <!-- 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="" />


  <!-- java源文件编码,编译的目标平台,为1.5 or 1.6都可以 -->


  <property name="java.encoding" value="UTF-8" />


  <property name="java.target" value="1.5" />


  <property name="java.source" value="1.5" />
<!-- Verbosity -->
  <property name="verbose" value="false" />
  <!-- 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" value="true">
  <and>
  <isset property="key.store" />
  <length string="${key.store}" when="greater" length="0" />
  <isset property="key.alias" />
  </and>
  </condition>
  <condition property="has.password" value="passwordxxxxx">
  <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.platform.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>
  <!-- sets the primary input for dex. If a pre-dex task sets it to
  something else this has no effect -->
  <property name="out.dex.input.absolute.dir" value="${out.classes.absolute.dir}" />
  <!-- set the secondary dx input: the project (and library) jar files
  If a pre-dex task sets it to something else this has no effect -->
  <if>
  <condition>
  <isreference refid="out.dex.jar.input.ref" />
  </condition>
  <else>
  <path id="out.dex.jar.input.ref">
  <path refid="jar.libs.ref" />
  </path>
  </else>
  </if>
  <echo>Converting compiled files and external libraries into ${intermediate.dex.file}…</echo>
  <apply executable="${dx}" failοnerrοr="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}" />
  <path refid="out.dex.jar.input.ref" />
  <external-libs />
  </apply>
  </sequential>
  </macrodef>


Android 自动 打包(三)



<!-- This is macro that enable passing variable list of external jar files to ApkBuilder
  Example of use:
  <package-helper 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="output.filepath" />
  <element name="extra-jars" optional="yes" />
  <sequential>
  <apkbuilder outfolder="${out.absolute.dir}" resourcefile="${resource.package.file.name}" apkfilepath="@{output.filepath}" debugpackaging="${build.packaging.debug}" debugsigning="${build.signing.debug}" abifilter="${filter.abi}" verbose="${verbose}" hascode="${manifest.hasCode}">
  <dex path="${intermediate.dex.file}" />
  <sourcefolder path="${source.absolute.dir}" />
  <sourcefolder refid="project.libraries.src" />
  <jarfolder path="${jar.libs.absolute.dir}" />
  <jarfolder refid="project.libraries.libs" />
  <nativefolder path="${native.libs.absolute.dir}" />
  <nativefolder refid="project.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}" failοnerrοr="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}" failοnerrοr="true">
  <arg line="${adb.device.arg}" />
  <arg value="install" />
  <arg value="-r" />
  <arg path="${out.debug.file}" />
  </exec>
  </sequential>
  </macrodef>
  <!-- Rules -->
  <!-- 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="${jar.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-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="-resource-src, -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}/${out.dir}/classes" else=".">
  <isset property="tested.project.absolute.dir" />
  </condition>
  <condition property="extensible.libs.classpath" value="${tested.project.absolute.dir}/libs" else="${jar.libs.dir}">
  <isset property="tested.project.absolute.dir" />
  </condition>
  <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">
  <src path="${source.absolute.dir}" />
  <src path="${gen.absolute.dir}" />
  <src refid="project.libraries.src" />
  <classpath>
  <fileset dir="${extensible.libs.classpath}" includes="*.jar" />
  </classpath>
  </javac>
  </then>
  <else>
  <echo>hasCode = false. Skipping…</echo>
  </else>
  </if>
  </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" />
  <!-- Obfuscate target
  This is only active in release builds when proguard.config is defined
  in default.properties.
  To replace Proguard with a different obfuscation engine:
  Override the following targets in your build.xml, before the call to <setup>
  -release-obfuscation-check
  Check whether obfuscation should happen, and put the result in a property.
  -debug-obfuscation-check
  Obfuscation should not happen. Set the same property to false.
  -obfuscate
  ** Make sure unless="do.not.compile" is used in the target definition **
  check if the property set in -debug/release-obfuscation-check is set to true.
  If true:
  Perform obfuscation
  Set property out.dex.input.absolute.dir to be the output of the obfuscation
  -->
  <target name="-obfuscate" unless="do.not.compile">
  <if condition="${proguard.enabled}">
  <then>
  <property name="obfuscate.absolute.dir" location="${out.absolute.dir}/proguard" />
  <property name="preobfuscate.jar.file" value="${obfuscate.absolute.dir}/original.jar" />
  <property name="obfuscated.jar.file" value="${obfuscate.absolute.dir}/obfuscated.jar" />
  <!-- input for dex will be proguard's output -->
  <property name="out.dex.input.absolute.dir" value="${obfuscated.jar.file}" />


Android 自动 打包(四)



<!-- Add Proguard Tasks --> 
<property name="proguard.jar" location="${proguard.home}/lib/proguard.jar" /> 
<taskdef name="proguard" classname="proguard.ant.ProGuardTask" classpath="${proguard.jar}" /> 


<!-- Set the android classpath Path object into a single property. It'll be 
all the jar files separated by a platform path-separator. 
--> 


<property name="android.libraryjars" refid="android.target.classpath" /> 
<!-- Build a path object with all the jar files that must be obfuscated. 
This include the project compiled source code and any 3rd party jar files. --> 


<path id="project.jars.ref"> 
<pathelement location="${preobfuscate.jar.file}" /> 
<path refid="jar.libs.ref" /> 
</path> 


<!-- Set the project jar files Path object into a single property. It'll be 
all the jar files separated by a platform path-separator. 
--> 


<property name="project.jars" refid="project.jars.ref" /> 
<mkdir dir="${obfuscate.absolute.dir}" /> 
<delete file="${preobfuscate.jar.file}" /> 
<delete file="${obfuscated.jar.file}" /> 
<jar basedir="${out.classes.dir}" destfile="${preobfuscate.jar.file}" /> 
<!-- 混淆相关参数 -->
<proguard>
  -optimizationpasses 5
  -dontusemixedcaseclassnames
  -dontskipnonpubliclibraryclasses
  -dontpreverify
  -verbose
  -repackageclasses
  -allowaccessmodification
  -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
  -keep public class * extends android.app.Activity
  -keep public class * extends android.app.Application
  -keep public class * extends android.app.Service
  -keep public class * extends android.content.BroadcastReceiver
  -keep public class * extends android.content.ContentProvider
  -keep public class com.android.vending.licensing.ILicensingService
  -injars ${project.jars}
  -outjars ${obfuscated.jar.file}
  -libraryjars ${android.libraryjars}
  </proguard>
  </then>
  </if>
  </target>
  <target name="pre" depends="-obfuscate">
  </target> 


 <!-- Converts this project's .class files into .dex files -->
  <!--<target name="-dex" depends="compile, -post-compile, -obfuscate" unless="do.not.compile">-->
  <target name="-dex" depends="compile, -post-compile, optimize" unless="do.not.compile">
  <if condition="${manifest.hasCode}">
  <then>
  <dex-helper />
  </then>
  <else>
  <echo>hasCode = false. Skipping…</echo>
  </else>
  </if>
  </target>
  <target name="optimize" depends="compile,-obfuscate">
  <if condition="${proguard.enabled}">
  <then>
  <mkdir dir="${out.dir}/out/class" />
  <!-- 创建文件夹-->
  <!--别人的<jar basedir="${out-folder}" destfile="temp.jar"/>-->
  <property name="proguard-jar" value="${proguard.home}/lib/proguard.jar" />
  <java jar="${proguard-jar}" fork="true" failοnerrοr="true">
  <jvmarg value="-Dmaximum.inlined.code.length=32" />
  <arg value="-injars ${out.dir}/classes" />
  <!-- 原来的类文件,使用Bin/classes下的-->
  <arg value="-outjars ${out.dir}/out/classes" />
  <!-- 生成的混淆Class位置-->
<arg value="-libraryjars ${android-jar}" />
  <!--
  <arg value=" -libraryjars ${library-jar}/some_lib_used.jar"/>
  -->
  <arg value="-keep public class * extends android.app.Activity" />
  <arg value="-keep public class * extends android.app.Service" />
  <arg value="-keep public class * extends android.content.BroadcastReceiver" />
  <arg value="-keep public class * extends android.content.ContentProvider" />
  <arg value="-keep public class * extends android.view.View" />
  <arg value="-dontwarn" />
  <arg value="-dontpreverify" />
  <arg value="-optimizationpasses 7" />
  <arg value="-dontusemixedcaseclassnames" />
  <arg value="-dontskipnonpubliclibraryclasses" />
  <arg value="-repackageclasses" />
  <arg value="-allowaccessmodification" />
  <!--<arg value="-dontskipnonpubliclibraryclassmembers"/>-->
  </java>


Android 自动 打包(五)



<!--这些是原来的Jar<delete file="temp.jar"/>-->
  <!--<delete dir="${out-folder}"/>-->
  <!--<mkdir dir="${out-folder}"/>
  <unzip src="optimized.jar" dest="${out-folder}"/>
  <delete file="optimized.jar"/>-->
  </then>
  </if>
  </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</echo>
  <aapt executable="${aapt}" command="package" versioncode="${version.code}" debug="${build.packaging.debug}" 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>
  </target>
  <!-- Packages the application and sign it with a debug key. -->
  <target name="-package-debug-sign" depends="-dex, -package-resources">
  <package-helper output.filepath="${out.debug.unaligned.file}" />
  </target>
  <!-- Packages the application without signing it. -->
  <target name="-package-release" depends="-dex, -package-resources">
  <package-helper 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="-debug-obfuscation-check">
  <!-- proguard is never enabled in debug mode -->
  <property name="proguard.enabled" value="true" />
  </target>
  <target name="-set-debug-mode" depends="-debug-obfuscation-check">
  <!-- property only set in debug mode.
  Useful for if/unless attributes in target node
  when using Ant before 1.8 -->
  <property name="build.mode.debug" value="true" />
  <!-- whether the build is a debug build. always set. -->
  <property name="build.packaging.debug" value="true" />
  <!-- signing mode: debug -->
  <property name="build.signing.debug" value="true" />
  </target>
 
<!-- Builds debug output package, provided all the necessary files are already dexed -->
  <target name="debug" depends="-set-debug-mode, -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>
  <!-- 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 -->
  <echo>Gets passwords ${has.keystore} ${has.password}</echo>
  <input message="Please enter keystore password (store:${key.store}):" addproperty="key.store.password" defaultvalue="5201314" />
  <input message="Please enter password for alias '${key.alias}':" addproperty="key.alias.password" defaultvalue="5201314" />
  </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="-release-obfuscation-check">
  <condition property="proguard.enabled" value="true" else="false">
  <and>
  <isset property="build.mode.release" />
  <isset property="proguard.config" />
  </and>
  </condition>
 
<if condition="${proguard.enabled}">
  <then>
  <!-- Secondary dx input (jar files) is empty since all the
  jar files will be in the obfuscated jar -->
  <path id="out.dex.jar.input.ref" />
  </then>
  </if>
  </target>
  <target name="-set-release-mode">
  <!-- release mode is only valid if the manifest does not explicitly
  set debuggable to true. default is false.
  We actually store build.packaging.debug, not build.release -->
  <xpath input="AndroidManifest.xml" expression="/manifest/application/@android:debuggable" output="build.packaging.debug" default="false" />
  <!-- signing mode: release -->
  <property name="build.signing.debug" value="false" />
  <if condition="${build.packaging.debug}">
  <then>
  <echo>*************************************************</echo>
  <echo>**** Android Manifest has debuggable=true ****</echo>
  <echo>**** Doing DEBUG packaging with RELEASE keys ****</echo>
  <echo>*************************************************</echo>
  </then>
  <else>
  <!-- property only set in release mode.
  Useful for if/unless attributes in target node
  when using Ant before 1.8 -->
  <property name="build.mode.release" value="true" />
  </else>
  </if>
  </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, -release-obfuscation-check, -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="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="deployableAllDevice" description="build all device packet">
  <!-- uid和sdk都是自定义参数,可有可无,有多小个包要打,就在这里copy多小行,修改相关参数,传入到程序里即可 -->
  <antcall target="release" inheritAll="true"><param name="uid" value="100" /><param name="sdk" value="91" /></antcall>
  <antcall target="release" inheritAll="true"><param name="uid" value="101" /><param name="sdk" value="90" /></antcall>
  </target>
  </project>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值