8.2 使用 Ant 脚本打包
在开始本节的内容之前,我们先要做一些准备工作,比如说准备好一份需要安装的软件清单,如下所示:
·Ant 1.9.2
·Antcontrib
·Java SDK 1.6
·CCNET
·IIS 6
·Android SDK 19
·SVN
接下来,我们开始安装上述这些软件,需要注意以下几点:
1)事先准备一个Android项目ProjectForAntBuild。
2)在服务器上安装Java SDK。注意,请安装1.6.0版本的jdk,1.7版本的打包时会有问题。
3)在服务器上安装Ant,版本为1.9.2。注意,请安装带有antcontrib扩展的Ant,它提供了for和if语句,能帮我们做更多的事情。
要定义3个全局变量,末尾记得加分号,如表8-1所示。
表8-1 定义一些全局变量
4)在服务器上安装Android SDK,我的demo是基于sdk-19的,大家可以根据自己的sdk版本配置自己的安装包。
5)对于Android 3.0以上版本的SDK,我们会发现apkbuilder.bat文件找不到了,我们需要上网去下载一个,或者从老版本的SDK把这个文件复制出来,然后粘贴到ddms.bat文件所在的目录中。
8.2.1 Android打包流程
一套完整的Android APK打包流程如图8-2所示,有的同学还会在最后一步加上adb指令将生成的apk包自动安装到手机上,这里没有包括这个步骤,因为我认为打出一个正式的安装包就算完成任务了。
打包脚本build.xml放在ProjectForAntBuild项目的根目录下,打包流程如图8-2所示,大家可以一边看着流程图一边看Ant打包脚本。
Android打包步骤如下所示:
1)初始化。准备打包使用的目录,同时声明各种全局变量。
<target name="init"> <delete dir="${outdir-gen}" /> <delete dir="${outdir}" /> <delete file="${basedir}/proguardMapping.txt" /> <mkdir dir="${outdir-gen}" /> <mkdir dir="${outdir-classes}" /> <mkdir dir="${outdir}/${appname}" /> <mkdir dir="${basedir}/${output.dir}" /> </target>
2)使用aapt生成R文件。根据res目录下的资源生成R.java文件。同时生成Android-Manifest.xml对应的Manifest.java文件。这两个文件位于Android项目的根目录下的gen子目录中。
<target name="aapt_gererateR" depends="init"> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-m" /> <arg value="-J" /> <arg value="${outdir-gen}" /> <arg value="-M" /> <arg value="${manifest-xml}" /> <arg value="-S" /> <arg value="${resource-dir}" /> <arg value="-I" /> <arg value="${android-jar}" /> </exec> </target>
3)aidl。将项目中的.aidl文件转换为.java代码。
<target name="aidl" depends="aapt_gererateR"> <apply executable="${aidl}" failonerror="true"> <arg value="-p${android-framework}" /> <arg value="-I${srcdir}" /> <arg value="-o${outdir-gen}" /> <fileset dir="${srcdir}"> <include name="**/*.aidl" /> </fileset> </apply> </target>
图8-2 Android打包流程图
4)javac。将项目中的所有Java代码编译为.class文件。
<target name="compile" depends="aidl"> <javac debug="true" extdirs="" srcdir="." includeantruntime="on" destdir="${outdir-classes}" bootclasspath="${android-jar}" encoding="UTF-8"> <compilerarg line="-encoding UTF-8 " /> <classpath> <fileset dir="${external-libs}" includes="*.so" /> <fileset dir="${external-libs}" includes="**/*.so" /> <fileset dir="${external-libs}" includes="*/*.so" /> <fileset dir="${external-libs}" includes="**/*.jar" /> </classpath> </javac> </target>
5)混淆。对项目进行混淆。同时生成proguardMapping.txt文件。
<target name="obfuscate" depends="compile"> <jar basedir="${outdir-classes}" destfile="temp.jar" /> <java jar="${proguard-home}/proguard.jar" fork="true" failonerror="true"> <jvmarg value="-Dmaximum.inlined.code.length=32" /> <arg value="-injars temp.jar" /> <arg value="-outjars optimized.jar" /> <arg value="-libraryjars '${annotations-jar}'" /> <arg value="-libraryjars '${android-jar}'" /> <arg value="@proguard-project.txt" /> </java> <delete file="temp.jar" /> <delete dir="${outdir-classes}" /> <mkdir dir="${outdir-classes}" /> <unzip src="optimized.jar" dest="${outdir-classes}" /> <delete file="optimized.jar" /> </target>
6)dex。将项目中的所有.class文件(包括第三方库的.class文件)转换为.dex文件。
<target name="dex" depends="obfuscate"> <apply executable="${dx}" failonerror="true" parallel="true"> <arg value="--dex" /> <arg value="--output=${intermediate-dex-ospath}" /> <arg path="${outdir-classes-ospath}" /> <arg path="${external-libs-ospath}" /> <fileset dir="${external-libs}" includes="*.so" /> <fileset dir="${external-libs}" includes="**/*.so" /> </apply> </target>
7)使用aapt打包资源。将res目录下的资源打包为一个.ap_文件。注意,不要忽略了assets目录下的资源。
<target name="aapt-package-res" depends="dex"> <echo>Packaging resources and assets… </echo> <echo>${resource-dir}</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-f" /> <arg value="-M" /> <arg value="${manifest-xml}" /> <arg value="-S" /> <arg value="${resource-dir}" /> <arg value="-A" /> <arg value="${asset-dir}" /> <arg value="-I" /> <arg value="${android-jar}" /> <arg value="-F" /> <arg value="${resources-package}" /> </exec> </target>
8)apkbuilder。将所有的dex文件、ap_文件、AndroidManifest.xml打包为.apk文件,这是一个未签名的包。
<target name="apkbuilder" depends="aapt-package-res"> <exec executable="${apk-builder}" failonerror="true"> <arg value="${out-unsigned-package-ospath}" /> <arg value="-u" /> <arg value="-z" /> <arg value="${resources-package-ospath}" /> <arg value="-f" /> <arg value="${intermediate-dex-ospath}" /> <arg value="-rf" /> <arg value="${srcdir-ospath}" /> <arg value="-nf" /> <arg value="${external-libs-ospath}" /> <arg value="-rj" /> <arg value="${basedir}\${external-libs}" /> </exec> </target>
9)jarsigner。对apk进行签名。
<target name="jarsigner" depends="apkbuilder"> <exec executable="${jarsigner}" failonerror="true"> <arg value="-verbose" /> <arg value="-keystore" /> <arg value="${key.store}" /> <arg value="-storepass" /> <arg value="${key.store.password}" /> <arg value="-keypass" /> <arg value="${key.alias.password}" /> <arg value="-signedjar" /> <arg value="${out-signed-package-ospath}" /> <arg value="${out-unsigned-package-ospath}" /> <arg value="${key.alias}" /> <arg value="-digestalg" /> <arg value="SHA1" /> <arg value="-sigalg" /> <arg value="MD5withRSA" /> </exec> </target>
10)zipalign。对要发布的apk文件进行对齐操作,以便在运行时节省内存。
<target name="zipalign" depends="jarsigner"> <exec executable="${zipalign}" failonerror="true"> <arg value="-v" /> <arg value="-f" /> <arg value="4" /> <arg value="${out-signed-package-ospath}" /> <arg value="${zipalign-package-ospath}" /> </exec> </target>
至此,Ant的build脚本都已经介绍完毕,我们只要执行下列语句,就可以对Android项目进行打包:
c:\ProjectForAntBuild>ant– buildfile build.xml
注意,上述Ant脚本打出来的包是签名包。
8.2.2 打包时的注意事项
容我再多说几句,以下内容是我在日常打包过程中的经验总结。
1)打包工作是件很枯燥的事情,一定要细心,要多使用echo输出日志。在cmd中看日志的问题是,一旦日志内容多了,前面的日志会被冲掉,所以请使用标签,把日志记录到本地文件中:
<project name="apkTargets" default="zipalign" basedir="."> <record name="C:/build.log" loglevel="info" append="no" action="start" />
2)一定要确保打包服务器上的Android SDK版本与开发人员所使用的开发版本一致。尤其是proguard程序,版本低了,会导致混淆不能进行。
3)如果打包机器上安装了杀毒软件,它会妨碍Android的打包工作,尤其是dex文件,会被视作一个病毒,所以apkbuilder会不能正常执行。切记,在打包机器上,一定要把杀毒软件关闭。
4)有时,我们需要打未签名的包,于是我们在上述打包脚本build.xml中补充以下语句:
<target name="debug" depends="aapt-package-res"> <exec executable="${apk-builder}" failonerror="true"> <arg value="${out-debug-package-ospath}" /> <arg value="-z" /> <arg value="${resources-package-ospath}" /> <arg value="-f" /> <arg value="${intermediate-dex-ospath}" /> <arg value="-rf" /> <arg value="${srcdir-ospath}" /> <arg value="-nf" /> <arg value="${external-libs-ospath}" /> <arg value="-rj" /> <arg value="${external-libs-ospath}" /> </exec> </target>
这条语句与前面介绍的打包流程第8步虽然都使用了apkbuilder指令,但是参数略有不同,所以打出来的包是未签名的。我们将Ant中project标签的default属性改为debug,执行以下指令即可:
c:\ProjectForAntBuild>ant– buildfile build.xml
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论