步骤:
1. 用 aapt工具生成R文件
aapt package -m -J gen目录 -M AndroidManifest.xml -S res目录 -I 编译版本sdk的android.jar的路径
如: "sdk安装目录\platforms\android-8\android.jar"
2. 用 aidl.exe 工具将.aidl文件生成对应的java类
3. 用 javac 编译所有的java文件,生成对应class文件。
4. 用 jar 命令将上面的class文件生成一个 jar包
5 用 proguard.jar 将上面的jar包混淆, (混淆应该是对class文件进行的,上面即使打包了可能也要解包,所以第4步可以省)
6. 用 dx.bat(调用了dx.jar)工具将混淆后的class文件,打包成一个 class.dex 文件
7. 用 aapt.exe 工具将 资源文件 打包成一个 resources.ap_ 文件(好像对整个res目录都压缩了,但是解压apk后图片又是分目录存放的)
8. 用 apkbuilder.bat(调用了lib目录的sdklib.build.ApkBuilderMain)将 dex文件和打包后的资源文件 生成 apk文件
9. 用 jarsigner 对apk 进行签名,生成签名后的 apk 文件
10.用 zipalign.exe 工具对签名后的 apk 进行优化,生成最终的 apk 文件
下面是对应的ant脚本(去掉了混淆的步骤)。
build.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="DailyBuild" default="buildAll" basedir="."> <!-- 导入可配置文件 --> <import file="build_option.xml" /> <!--导入构建过程定义文件 --> <import file="build_common.xml" /> <!-- 调用common_build.xml中的target,按顺序组织,执行构建 <antcall target="obfuscate" />--> <target name="buildAll"> <antcall target="init" /> <antcall target="generate" /> <antcall target="aidl" /> <antcall target="compile" /> <antcall target="package" /> <antcall target="dex" /> <antcall target="package_resouces" /> <antcall target="release" /> <antcall target="sign" /> <antcall target="zipalign" /> </target> </project>
build_common.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="build_common" default="" basedir="."> <property name="src" value="src"/> <!-- 运行时源代码目录 --> <property name="res" value="res"/> <!-- 运行时资源目录 --> <property name="lib" value="libs"/> <!-- 运行时库目录 --> <property name="assets" value="assets"/> <!-- 运行时assets目录 --> <property name="bin" value="bin"/> <!-- 编译输出结果目录 --> <property name="classes" value="classes"/> <!-- 运行时classes输出目录 --> <property name="gen" value="gen" /> <!-- 运行时gen目录 --> <property name="autotest" value="autotest" /> <!-- 自动化测试目录 --> <property name="dex" value="classes.dex"/> <!-- dex路径 --> <property name="android_platform_tools" value="${android_home}/platform-tools"/> <property name="android_framework" value="${android_home}/platforms/android-${android_version}/framework.aidl"/> <property name="aapt" value="${android_platform_tools}/aapt"/> <property name="aidl" value="${android_platform_tools}/aidl"/> <property name="adb" value="${android_platform_tools}/adb"/> <property name="dx" value="${android_platform_tools}/dx${bat}"/> <property name="apkbuilder" value="${android_home}/tools/apkbuilder${bat}"/> <property name="zipalign" value="${android_home}/tools/zipalign"/> <property name="androidjar" value="${android_home}/platforms/android-${android_version}/android.jar"/> <!-- 执行初始化操作 --> <target name="init"> <echo>start initialize...</echo> <delete includeemptydirs="true" failonerror="false"> <fileset dir="${classes}" defaultexcludes="true"/> <fileset dir="${gen}" defaultexcludes="true"/> <fileset dir="${bin}" defaultexcludes="true"/> </delete> <mkdir dir="${bin}" /> <mkdir dir="${classes}" /> <mkdir dir="${gen}" /> <mkdir dir="${lib}" /> </target> <!-- 生成R.java --> <target name="generate"> <echo>generate R.java ...</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-m" /> <arg value="-J" /> <arg value="${gen}" /> <arg value="-M" /> <arg value="AndroidManifest.xml" /> <arg value="-S" /> <arg value="${res}" /> <arg value="-I" /> <arg value="${androidjar}" /> </exec> </target> <!-- 将aidl文件转换为java --> <target name="aidl"> <echo>convert .aidl files to java...</echo> <apply executable="${aidl}" failonerror="true"> <arg value="-p${android_framework}" /> <arg value="-I${src}" /> <arg value="-o${gen}" /> <fileset dir="${src}"> <include name="**/*.aidl"/> </fileset> </apply> </target> <!-- 编译项目的.java文件 --> <target name="compile"> <echo>compile source code...</echo> <echo>>>>> debug默认打开,异常上报的还原功能依赖于它</echo> <javac encoding="${encoding}" debug="true" extdirs="" target="1.5" destdir="${classes}" bootclasspath="${androidjar}"> <src path="${src}"/> <src path="${gen}"/> <classpath> <fileset dir="${lib}" includes="*.jar"/> </classpath> </javac> </target> <!-- 将class文件打包为jar --> <target name="package"> <echo>Packing compile results...</echo> <jar basedir="${classes}" destfile="temp.jar"/> <echo>Copy jar to test directory...</echo> <copy file="temp.jar" todir="${autotest}"/> </target> <!-- 对打包后的结果进行混淆 --> <target name="obfuscate" if="${release}"> <echo>start obfuscate ...</echo> <delete includeemptydirs="true"> <fileset dir="${classes}" defaultexcludes="true"/> </delete> <java jar="${proguard_home}/lib/proguard.jar" fork="true" failonerror="true"> <jvmarg value="-Dmaximum.inlined.code.length=32"/> <arg value="-injars temp.jar"/> <!-- 输入为class目录,而不是jar包,可以提高速度 --> <arg value="-outjars ${classes}"/> <!-- 输出为class目录,而不是jar包,可以提高速度 --> <arg value="-libraryjars ${androidjar}"/> <arg value="-libraryjars ${lib}"/> <!-- 混淆依赖的库文件,指定目录即可 --> <arg value="-printmapping ${bin}/mapping.txt"/> <!-- 混淆mapping信息 --> <arg value="@proguard.cfg"/> <!-- 混淆参数定义 --> </java> </target> <!-- 将未混淆的classes文件打包为dex文件 --> <target name="dex"> <echo>Coverting obfuscated class files to dex file...</echo> <apply executable="${dx}" failonerror="true" parallel="true"> <arg value="-JXms1024m" /> <arg value="-JXmx1024m" /> <arg value="-JXss160k" /> <arg value="--dex" /> <arg value="--num-threads=4" /> <arg value="--output=${dex}" /> <arg path="${classes}" /> <fileset dir="${lib}" includes="*.jar"/> </apply> </target> <!-- 打包项目的资源文件 --> <target name="package_resouces"> <echo>Package res and assets...</echo> <exec executable="${aapt}" failonerror="true"> <arg value="package" /> <arg value="-f" /> <arg value="-M" /> <arg value="AndroidManifest.xml" /> <arg value="-S" /> <arg value="${res}" /> <arg value="-A" /> <arg value="${assets}" /> <arg value="-I" /> <arg value="${androidjar}" /> <arg value="-F" /> <arg value="${file_name}.ap_" /> </exec> </target> <!-- 将资源文件及dex文件打包到一起 --> <target name="release"> <echo>package dex and resources ...</echo> <exec executable="${apkbuilder}" failonerror="true"> <arg value="${file_name}.apk" /> <arg value="-u" /> <arg value="-z" /> <arg value="${file_name}.ap_" /> <arg value="-f" /> <arg value="${dex}" /> <arg value="-rf" /> <arg value="${src}" /> <arg value="-rj" /> <arg value="${lib}" /> <arg value="-nf" /> <arg value="${lib}" /> </exec> </target> <!-- 对包未混淆的包进行签名 --> <target name="sign"> <echo>Begin sign unobfuscated package...</echo> <exec executable="${signer}" failonerror="true"> <arg value="-verbose"/> <arg value="-keystore"/> <arg value="${keystore}"/> <arg value="-storepass"/> <arg value="${storepass}"/> <arg value="-keypass"/> <arg value="${keypass}"/> <arg value="-signedjar"/> <arg value="${file_name}_signed.apk"/> <arg value="${file_name}.apk"/> <arg value="${keyname}"/> </exec> </target> <!-- 对未混淆签名包做优化 --> <target name="zipalign"> <echo>zipalign signed apk ...</echo> <exec executable="${zipalign}" failonerror="true"> <arg value="-v" /> <arg value="4" /> <arg value="${file_name}_signed.apk" /> <arg value="${bin}/${file_name}_${cur_time}.apk" /> </exec> </target> </project>
build_option.xml
<?xml version="1.0" encoding="UTF-8"?> <project name="option" default="" basedir="."> <property environment="env" /> <!-- 环境变量 --> <property name="ws" value="${env.WORKSPACE}"/> <!-- 取服务器Woskspace路径 --> <property name="isCI" value="false"/> <!-- true表示服务器环境,false表示本地环境 --> <available file="${ws}/build.xml" property="isCI"/> <!-- 判断是否是持续集成服务器环境 --> <property name="android_sdk_path" value="${env.ANDROID_SDK_18_2204_16}" /> <!-- 取sdk路径--> <property name="android_version" value="8"/> <property name="encoding" value="UTF-8"/> <!-- 文件编码设置 --> <property name="release" value="true"/> <!-- 默认输出release版本,带混淆 --> <condition property="releasetype" value="debug" else="release"> <not> <istrue value="${release}"/> </not> </condition> <condition property="bat" value="bat" else=""> <os family="windows" /> </condition> <!-- 判断系统类型 --> <condition property="isWindows" value="true" else="false"> <os family="windows" /> </condition> <!-- 根据系统类型,设置服务器Android SDK路径 --> <condition property="android_home_accord_ostype" value="${android_sdk_path}" else="D:/android-sdk-windows" > <not> <istrue value="${isWindows}"/> </not> </condition> <!-- 根据系统类型,设置服务器Proguard路径 --> <condition property="proguard_path_accord_ostype" value="${env.ANDROID_PROGUARD_4_8}" else="C:/Progra~1/proguard4.4" > <not> <istrue value="${isWindows}"/> </not> </condition> <!-- 安装包名称,如果是本地,设置value的值 --> <condition property="file_name" value="RDM" else="${env.BaseLine}"> <not> <istrue value="${isCI}"/> </not> </condition> <!-- 本地工作区路径,如:D:/workspace/qqbrowser_android --> <condition property="project_path" value="${basedir}" else="${basedir}"> <not> <istrue value="${isCI}"/> </not> </condition> <!-- Android SDK路径,如果本地构建,请修改value的值 --> <condition property="android_home" value="C:/android-sdk-windows" else="${android_home_accord_ostype}"> <not> <istrue value="${isCI}"/> </not> </condition> <!-- Proguard路径,如果本地构建,请修改value的值 --> <condition property="proguard_home" value="C:/Progra~1/proguard4.4" else="${proguard_path_accord_ostype}"> <not> <istrue value="${isCI}"/> </not> </condition> <!-- 签名使用的jarsigner路径,如果JDK的bin目录路径已加入系统Path,则不用注明具体路径 --> <condition property="signer" value="jarsigner" else="jarsigner"> <not> <istrue value="${isCI}"/> </not> </condition> <property name="config_keystore_name" value="weigou_shop_keystore" /> <!-- 签名文件设置,请将签名文件放到SVN上,并在这里指定签名文件,建议将签名文件放到构建脚本同级目录,${project_path}即为工作目录--> <property name="keystore" value="${project_path}/${config_keystore_name}"/> <!-- 签名的密钥名称设置--> <property name="keyname" value="weigou_shop"/> <!-- 签名的密码设置--> <property name="keypass" value="201310161450"/> <!-- 签名的密码设置--> <property name="storepass" value="20131016"/> <tstamp> <format property="cur_time" pattern="yyyy_MM_dd_hh.mm" locale="zh"/> </tstamp> </project>
aidl是 Android Interface definitionlanguage的缩写。
它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口
aapt即Android Asset Packaging Tool , 在SDK的build-tools目录下:aapt.exe
该工具可以查看, 创建, 更新ZIP格式的文档附件(zip, jar, apk). 也可将资源文件编译成二进制文件.
aapt工具也支持很多子命令。
aapt l[ist]:列出资源压缩包里的内容。
aapt d[ump]:查看APK包内指定的内容。
aapt p[ackage]:打包生成资源压缩包。
aapt r[emove]:从压缩包中删除指定文件。
aapt a[dd]:向压缩包中添加指定文件。
aapt v[ersion]:打印aapt的版本。