android自动打包方法(ant+proguard+签名)_weixin_34124651的博客-程序员宅基地

技术标签: java  移动开发  

前段时间做了一个android的网游项目,现在优化减少体积和防止别人反编译,需要把编译后.class进行混淆,开始在网上看了一些关于 ProGuard的介绍,基本上都是使用ADT自带的打包方式,那个打包方式太慢了,还要手工输密码,一个字烦。

于是开始寻找ant+proguard+签名的打包方式,遗憾的是资料不是缺手就是断脚。
好吧,看来得食自己了,!@#¥@#!@#!@##¥@#¥!@#@ 转眼一周,我++,终于把东西搞出来
ps:我们项目还有一个特殊需求,要把版本号,推广ID打到包里去,方便做推广什么的。这里可以用replace的方法对string.xml进行修改
好吧,废话不说了,直接上build文件 
 
 
1. [代码][xml]代码     跳至 [1] [全屏预览]
 
<?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_" />
 
<!-- 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>
 
<!-- 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-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="-resource-src" depends="-dirs, -pre-build">
<if condition="${manifest.hasCode}">
<then>
<echo>Generating R.java / Manifest.java from the resources...</echo>
<aapt executable="${aapt}" command="package" verbose="${verbose}" manifest="AndroidManifest.xml" androidjar="${android.jar}" rfolder="${gen.absolute.dir}">
<res path="${resource.absolute.dir}" />
</aapt>
</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="project.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="-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}" />
 
<!-- 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>
<!--这些是原来的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>
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34124651/article/details/85642781

智能推荐

云计算、云原生与容器学习笔记-基础概念_Sindweller5530的博客-程序员宅基地

集中式还是分布式?关于云的架构,我目前还是比较混乱。。。一般情况下,有一个包含大量物理计算资源的云计算中心,从海量用户或终端设备收集的数据发送到云计算中心去计算并返回。边缘计算为什么需要边缘计算?云计算中心有可能离用户很远,用户需要经过多跳连接到云计算中心。可能导致的问题就是会有较大的时延,并且带宽也降低了,不能及时返回指令是很可怕的事情。那就会想让云计算能力跨越广域网,延伸到网络边缘来提供计算、存储和网络带宽。边缘站点更靠近用户,对于视频直播这种实时性要求很高的服务来说会比云计算中心处理并多跳

Java——模拟实现ArrayList和LinkedList类(一)_monologuezjp的博客-程序员宅基地

由于数组一旦定义,其长度就无法改变,某些情况下给我们的编程带来了不便。Java提供了两个集合——ArrayList类和LinkedList类,用来代替数组,有效解决了数组长度不能动态改变的问题。为了加深对数组和这两个集合类的理解,于是模拟这两个类实现了两个Box类,用来代替Array。为了方便,这里只实现了存储int类。模拟实现ArrayListArrayList 的好处是:可以动态增...

用Eclipse调试Node.js代码_赶路人儿的博客-程序员宅基地_eclipse调试js代码

1、在eclipse上安装v8插件: 1)Help>Install New Software ,在弹出的界面上点击Add,然后输入name和location两个信息,如下图:Name:随便取一个;location:http://chromedevtools.googlecode.com/svn/update/dev/注:安装的时候需要使用vpn,因为这里的地址是请求到了go

【考研高数-线性代数-强化】第四章 线性方程组(重点,别马虎大意)_刘鑫磊up的博客-程序员宅基地

【考研高数-线性代数-基础】第四章 线性方程组【重点】课本讲义:P82~P111一:网络结构网络图二:基本内容与重要结论1.基础知识2.主要定理三:典型例题1.基础解系2.解方程组Ax=b通用方程组求解: 1.已知方程组 同解变形(行变换)讨论参数 2.抽象方程组 秩、解的结构、推理分析一:齐次方程组Ax=0 n-r(A)线性无关的解向量、基础解系二:非齐次方程组Ax=b 有解判...

73.ORM聚合函数详解:Count_长大的小蚂蚁的博客-程序员宅基地

Count:用来求某个数据的个数。在以下所有的示例中所采用的模型为:from django.db import models# 定义作者模型class Author(models.Model): name = models.CharField(max_length=100, unique=True) age = models.IntegerField() ema...

ZUPT的相关初步理解_slam让我头疼的博客-程序员宅基地_zupt算法

参考至https://zhuanlan.zhihu.com/p/115529319零速修正(Zero Velocity Update, ZUPT)即,当载体处于静止状态时,载体此时的速度为零,利用载体中的惯性系统的解算速度作为系统速度误差的观测量,对其他误差量进行修正,改善静止状态下的组合导航结果,不需要增加外部传感器,因而是一种有效且廉价易实现的技术。零速修正一般方法利用卡尔曼滤波进行。当检测到载体处于静止状态时,利用SINS子系统解算的速度作为系统速度误差的观测量,进行卡尔曼滤波估计,利用更新后的

随便推点

mysql zimbra_Zimbra 相关设置_爱家小厨酱的博客-程序员宅基地

zimbra 相关的一些设置,不定期更新。更换 Logo 图标和链接mkdir /opt/zimbra/jetty/webapps/zimbra/logos/zmprov mcf zimbraSkinLogoURL https://mail.exsvc.cnzmprov md exsvc.cn zimbraSkinLogoURL https://mail.exsvc.cnzmprov md exs...

提升 iOS 开发效率! Xcode 9 内置模拟器的9个技巧_weixin_34324081的博客-程序员宅基地

iOS模拟器是在开发任意iOS应用程序过程中不可或缺、无法被忽视的一个部分。值得一提的是,Xcode 9的新模拟器带来了很多有用的功能,能够提升你的开发效率。对比历代模拟器的更新,这次有了很重大的改变。所以让我们开始这篇教程的重点吧,本文会列出我在新iOS模拟器中发现的新功能(一些技巧也可以在旧的模拟器中使用)。1. 在全屏模式下使用Xcode模拟器当你使用13寸的 Mac 时,Xcode ...

MySQL 基础 ———— 视图的应用与总结_圣斗士Morty的博客-程序员宅基地

引言视图是一种虚拟表,和普通表的使用是一样的,视图的一大特点就是“临时性”,是通过表动态生成的数据,只保存SQL逻辑,不保存查询结果。视图在实际生产中主要有两种应用场景:1、多个地方用到同样的查询结果;2、该查询使用的SQL比较复杂。下面,我们来总结一下这个在开发中经常会用到的知识点。一、视图的优势首先,视图并不能提高SQL的性能,它的作用在于更好的组织数据。优势有以下...

Mirai实现QQ机器人_只是六号z的博客-程序员宅基地_mirai机器人

Mirai实现机器人Java实现QQ机器人教程1.拉取项目demo2.修改配置文件3.滑动窗口验证(1)配置JVM参数(2)启动项目(3)获取ticket①让手机和电脑连接②开启调试模式③进行滑动验证4.简单测试Java实现QQ机器人教程要想实现Java版的QQ机器人,其实并不难,今天就给大家分享一下使用Mirai框架制作简单的QQ机器人。1.拉取项目demo首先,Miari是一个开源的框架,我们可以从GitHub上拉取项目进行查看,但是GitHub需要使用加速插件才能很好的访问,所以在这里我们可以

在centOs 上搭建nginx来部署静态页面网站_weixin_34392435的博客-程序员宅基地

2019独角兽企业重金招聘Python工程师标准&gt;&gt;&gt; ...

LibreOJ #2036. 「SHOI2015」自动刷题机_weixin_30302609的博客-程序员宅基地

#2036. 「SHOI2015」自动刷题机内存限制:256 MiB时间限制:1000 ms标准输入输出题目类型:传统评测方式:文本比较题目描述曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷...