参考学习资料
Android 引用 jar包有资源文件
http://blog.chinaunix.net/uid-7769108-id-2342109.html
使用Ant打包Android 应用
http://www.oschina.net/question/54100_30501
Android通过ant脚本打包带Library project的方法
http://blog.csdn.net/wanglin754/article/details/18000315
android ant多渠道混淆打包
http://blog.csdn.net/junfeng120125/article/details/9234651
1、基本打包过程
参考之上的使用Ant打包Android 应用,里面详细描述了ant基本打包的每一个阶段和基本命令的含义,非常有用!
2、遇到问题
2.1 bat命令找不到的问题
<span style="font-size:18px;"> <property name="aapt" value="${sdk-platform-tools}/aapt" />
<property name="aidl" value="${sdk-platform-tools}/aidl" />
<property name="dx" value="${sdk-platform-tools}/dx.bat" />
<property name="apkbuilder" value="${sdk-tools}/apkbuilder.bat" />
<property name="jarsigner" value="${env.JAVA_HOME}/bin/jarsigner" />
<property name="zipalign" value="${sdk-tools}/zipalign" /></span>
以上是Android自带的打包命令,如果在打包过程中出现命令找不到问题,可以仔细检查对应的文件夹下是否存在这些执行命令文件,在android sdk里面可以找到对应的命令文件。
2.2 apkbuilder.bat 取消的问题
在android3.0之后吧,这个不是很确定,apkbuilder.bat 这个执行命令就已经取消拿掉了。
<!-- 打包成未签证的apk -->
<target name="package" depends="dex,package-res-and-assets">
<echo>打包成未签证的apk....</echo>
<java classpath="${sdk-tools}/lib/sdklib.jar" classname="com.android.sdklib.build.ApkBuilderMain">
<!-- 输出路径 -->
<arg value="${out-unsigned-package-ospath}" />
<arg value="-u" />
<arg value="-z" />
<!-- 资源压缩包 -->
<arg value="${resources-package-ospath}" />
<arg value="-f" />
<!-- dex压缩文件 -->
<arg value="${dex-ospath}" />
<arg value="-rj" />
<arg value="${external-lib-ospath}"/>
<!-- 将主项目libs下面的so库打包 -->
<arg value="-nf" />
<arg value="${external-lib-ospath}" />
</java>
</target>
android sdk tools文件夹下 lib sdklib.jar就提供了对应的打包命令。
2.3多项目引用的问题
Android项目开发过程中,会出现主项目引用其他项目,其他做项目作为library导入,如何实现多项目的导入呢?
刚开始,我只是单纯的认为,导入项目源码;使用jar包就可以了,但是如果引用的项目设计到资源文件呢?
生成Appproject R.java
<span style="font-size:18px;"> <!-- 生成app project的 R.java-->
<exec
executable="${aapt}"
failοnerrοr="true" >
<arg value="package" />
<arg value="-m" />
<arg value="--auto-add-overlay" />
<arg value="-J" />
<arg value="${out-dir-gen}" />
<arg value="-M" />
<arg value="${destdir}\AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-S" />
<arg value="${library-dir}" />
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
</exec>
<!-- 生成liibrary project的 R.java-->
<exec
executable="${aapt}"
failοnerrοr="true" >
<arg value="package" />
<arg value="-m" />
<arg value="--auto-add-overlay" />
<arg value="-J" />
<arg value="${out-dir-gen}" />
<arg value="-M" />
<arg value="${library-dir}\AndroidManifest.xml" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-S" />
<arg value="${library-dir}" />
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
</exec> </span>
刚开始我是按照这种做法来实现的,然后在打包完成之后,凡是涉及到引入项目资源的时候就会报错,为什么呢?我反编译打包的apk,查看源码之后清楚的看到,在源码里面会发现多个R.java文件,每一个引用的library项目都会有一个自己的R.java文件;主项目R.java会包含所有子项目的R.java中资源名称,但是可能会出现对应的ID整数值是不一样的。下面说说报错的原因:
转移资源文件
<span style="font-size:18px;"><!-- 将资源文件放进输出目录 -->
<target name="package-res-and-assets">
<echo>将资源文件放进输出目录....</echo>
<exec executable="${aapt}" failοnerrοr="true">
<arg value="package" />
<arg value="-f" />
<arg value="-M" />
<arg value="${manifest-xml}" />
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-S"/>
<arg value="${library-dir}/res"/>
<arg value="-S"/>
<arg value="${library-dir2}/res"/>
<arg value="-A" />
<arg value="${asset-dir}" />
<arg value="-I" />
<arg value="${android-jar}" />
<arg value="-F" />
<arg value="${resources-package}" />
<arg value="--auto-add-overlay" />
</exec>
</target></span>
资源转移部分中,他会将主项目,引用的library项目的所有资源文件整合到一起;多个项目共用一套资源文件夹,就像单纯一个项目时的资源目录一样;然后在子项目里面我们引用的R.java是子项目中的R.java文件。通过项目源码引入的包名可以知道。
AppPjoject R.java生成部分 是整合资源生成主项目R.java和子项目R.java的部分,可以看出,他会整合所有的资源统一使用主项目的R.java文件,任何资源文件都会通过主项目的R.java文件的对应ID整数值去查找,问题也就出来了,子项目查找资源文件通过子项目的R.java;而主项目的R.java的资源整数值与子项目可能就会出现不同,就会出现资源找不到,app运行不了的情况!
如果我可以是主项目和子项目的R.java保持统一的话,问题就解决了!
修改后的 AppPjoject R.java
<span style="font-size:18px;"><!-- 根据工程中的资源文件生成R.java文件 -->
<target name="gen-R" depends="init">
<echo>生成R.java文件....</echo>
<exec executable="${aapt}" failοnerrοr="true">
<arg value="package" />
<arg value="-m" />
<arg value="--auto-add-overlay" />
<arg value="-J" />
<!--R.java文件的生成路径-->
<arg value="${outdir-gen}" />
<!-- 指定清单文件 -->
<arg value="-M" />
<arg value="${manifest-xml}" />
<!-- 指定资源目录 -->
<arg value="-S" />
<arg value="${resource-dir}" />
<arg value="-S" />
<arg value="${library-dir}/res" /><!-- 注意点:同时需要调用Library的res-->
<arg value="-S" />
<arg value="${library-dir2}/res" /><!-- 注意点:同时需要调用Library的res-->
<arg value="--extra-packages" />
<arg value="${extra-library-packages}" />
<!-- 导入类库 -->
<arg value="-I" />
<arg value="${android-jar}" />
</exec>
</target>
</span>
修改之后,我们发现主项目或者子项目的R.java文件的生成,都使用同一个manifest清单文件,所有最终library项目和主项目生成的R.java文件一模一样,之上的问题也就解决了!
2.4避免重复引用jar包问题
编译主项目
<span style="font-size:18px;"> <!-- 主应用编译class -->
<javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}" >
<compilerarg line="-encoding UTF-8 " />
<!-- <compilerarg line="-encoding UTF-8 "/> -->
<src path="${basedir}/src" /><!-- 工程源码-->
<src path="${outdir-gen}" /><!--R.java 资源类的导入 -->
<!-- 编译java文件依赖jar包的位置 -->
<classpath>
<fileset dir="${external-lib}" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译 -->
<fileset dir="${external-compile-lib}" includes="*.jar"/><!-- 第三方jar包需要引用,用于辅助编译 -->
<fileset dir="${external-library-dir-lib-ospath}" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译 -->
</classpath>
</javac>
</target></span>
我们的主项目可能使用多个子项目library,子项目之间也可能存在引用嵌套的关系;所以在引第三方jar包的时候;如果子项目1需要引用,同时主项目也需要引用;那么我们可以把第三方jar包放到子项目中,在打包的时候,记住classpath路径设置上需要对引用的第三方的jar包进行设置!否则,会出现第三方jar包找不到,打包失败!
2.5第三方jar包含有资源文件问题
第三方jar包可能会含有xml,图片等资源文件(例如百度地图jar),我们如何才能按照jar的文件路径完整的将资源文件放置到apk目录中呢?如果按照jar包的路径设置进去的话,同样也会出现在调用第三方jar包时,找不到对应的额资源文件,出现app运行失败的问题。
<span style="font-size:18px;"><!-- 打包成未签证的apk -->
<target name="package" depends="dex,package-res-and-assets">
<echo>打包成未签证的apk....</echo>
<java classpath="${sdk-tools}/lib/sdklib.jar" classname="com.android.sdklib.build.ApkBuilderMain">
<!-- 输出路径 -->
<arg value="${out-unsigned-package-ospath}" />
<arg value="-u" />
<arg value="-z" />
<!-- 资源压缩包 -->
<arg value="${resources-package-ospath}" />
<arg value="-f" />
<!-- dex压缩文件 -->
<arg value="${dex-ospath}" />
<arg value="-rj" />
<arg value="${external-lib-ospath}"/>
<!-- 将主项目libs下面的so库打包 -->
<arg value="-nf" />
<arg value="${external-lib-ospath}" />
</java>
</target></span>
关键点
<span style="font-size:18px;"> <arg value="-rj" />
<arg value="${external-lib-ospath}"/></span>
这一步,会将引用的第三方jar以及其中的资源文件,按照一定的格式放置到apk文件夹中!
2.6多渠道打包的问题
其实这块比较简单,基本没有出现什么问题;主要引用ant-contrib-1.0b3.jar根据渠道号实现循环调用单次打包,最终是实现多渠道打包!
参考文件下载地址:
http://download.csdn.net/detail/mao520741111/7920507