• 2968阅读
  • 1回复

关于ant 打包android引入第三方类库library project的终极解决方案 [复制链接]

上一主题 下一主题
离线太史慈
 

发帖
777
金币
626
威望
556
只看楼主 倒序阅读 使用道具 楼主  发表于: 2013-08-21
==========前言==========
网上搜了很多种方案,但大多说得比较笼统
比如:
1、关于ant 打包android progect同时引入第三方library project注意点
http://blog.csdn.net/zah5897/article/details/8863864

2、android ant打包 引用第三方library
http://my.eoe.cn/712685/archive/4335.html

3、ant-build.xml打包应用程序【总结】
http://www.blogjava.net/1504/archive/2009/04/15/265851.html

后来尝试了一下,又准备放弃,改用maven来打包,不过考虑到学习成本比较大...
不过后来还是在ant的基础上搞出来了,此帖不光能解决一个library的依赖问题,还能解决多个library递归依赖的问题。

==========正文==========
废话不多说,贴上build.xml
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project name="ProjectName" default="release" basedir=".">
  3. <property file="config.properties"/>
  4.     <property file="ProjectHome.properties"/>
  5.     <!-- ANT环境变量 -->
  6.     <property environment="env" />
  7.     <!-- 生成R文件的相对目录 -->
  8.     <property name="outdir-gen" value="${project.home}/gen" />
  9.     <!-- 编译后的文件放置目录 -->
  10.     <property name="outdir-bin" value="${project.home}/bin" />
  11.     <!-- 输出目录 -->
  12. <property name="outdir" value="${project.outdir}" />
  13.     <!-- 清单文件 -->
  14.     <property name="manifest-xml" value="${project.home}/AndroidManifest.xml" />
  15.     <!-- 源文件目录 -->
  16.     <property name="resource-dir" value="res" />
  17.     <property name="asset-dir" value="assets" />
  18.     <!-- 资源文件目录 -->
  19.     <property name="drawable-dir" value="${resource-dir}/drawable" />
  20.     <property name="drawable-hdpi-dir" value="${resource-dir}/drawable-hdpi"/>
  21.     <property name="drawable-ldpi-dir" value="${resource-dir}/drawable-ldpi"/>
  22.     <property name="drawable-mdpi-dir" value="${resource-dir}/drawable-mdpi"/>
  23.     <property name="drawable-zh-rCN-dir" value="${resource-dir}/drawable-zh-rCN"/>
  24.     <!-- java源文件目录 -->
  25.     <property name="srcdir" value="src" />
  26.     <property name="srcdir-ospath" value="${project.home}/${srcdir}" />
  27.     <!-- 动态库so文件目录 -->
  28.     <property name="library" value="${project.home}/libs" />
  29.     <!-- 第三方library -->
  30.     <property name="library-dir" value="${library-dir}" />
  31.     <property name="library-dir2" value="${library-dir2}" />
  32.     <!-- 外部类库所在目录 -->
  33.     <property name="external-lib" value="lib" />
  34.     <property name="external-lib-ospath" value="${project.home}/${external-lib}" />
  35.     <!-- 生成class目录 -->
  36.     <property name="outdir-classes" value="${outdir-bin}/classes" />
  37.     <property name="outdir-classes-ospath" value="${outdir-classes}" />
  38.     <!-- classes.dex相关变量 -->
  39.     <property name="dex-file" value="classes.dex" />
  40.     <property name="dex-path" value="${outdir-bin}/${dex-file}" />
  41.     <property name="dex-ospath" value="${dex-path}" />
  42.     <!-- 经过aapt生成的资源包文件 -->
  43.     <property name="resources-package" value="${outdir-bin}/resources.ap_" />
  44.     <property name="resources-package-ospath" value="${resources-package}" />
  45.     <!-- 未认证apk包 -->
  46.     <property name="out-unsigned-package" value="${outdir-bin}/${appName}-unsigned.apk" />
  47.     <property name="out-unsigned-package-ospath" value="${out-unsigned-package}" />
  48.     <!-- 证书文件 -->
  49.     <property name="keystore-file" value="${keystore}" />
  50.     <!-- 已认证apk包 -->
  51.     <property name="out-signed-package" value="${outdir-bin}/${appName}.apk" />
  52.     <property name="out-signed-package-ospath" value="${out-signed-package}" />
  53.     <!-- 已优化apk包 -->
  54.     <property name="zipalign-signed-package" value="${outdir-bin}/${appName}${version}_release.apk" />
  55.     <!-- 输出路径的apk包 -->
  56.     <property name="outdir-package" value="${project.outdir}/${appName}.apk" />
  57.     <!-- 初始化工作 -->
  58.     <target name="init">
  59.         <echo>Initializing all output directories...</echo>
  60.         <delete dir="${outdir-bin}" />
  61.         <delete dir="${outdir-gen}" />
  62.         <mkdir dir="${outdir-gen}" />
  63.         <mkdir dir="${outdir-bin}" />
  64.         <mkdir dir="${outdir-classes}" />
  65.     <!-- 把缺少的BuildConfig复制进去,暂时不知道如何生成 -->
  66.         <copy file="ZI-master-BuildConfig.java" tofile="${outdir-gen}/com/yixia/zi/BuildConfig.java">
  67.              <filterset>
  68.                 <filter token="CONFIG.FROM" value="${package.from}"/>
  69.              </filterset>
  70.         </copy>
  71.         <copy file="VitamioBundle-BuildConfig.java" tofile="${outdir-gen}/com/yixia/vitamio/library/BuildConfig.java">
  72.              <filterset>
  73.                 <filter token="CONFIG.FROM" value="${package.from}"/>
  74.              </filterset>
  75.         </copy>
  76.     </target>
  77.     <!-- 根据工程中的资源文件生成R.java文件 -->
  78.     <target name="GenRJAVA" depends="init">
  79.         <echo>Generating R.java / Manifest.java from the resources...</echo>
  80.         <exec executable="${android-aapt}" failonerror="true">
  81.             <arg value="package" /><!-- package表示打包-->
  82.             <arg value="-m" /><!--m,J,gen表示创建包名的目录和R.java到gen目录下 -->
  83.             <arg value="-J" />
  84.             <arg value="${outdir-gen}" />
  85.             <arg value="-M" /><!-- M指定AndroidManifest.xml文件-->
  86.             <arg value="${manifest-xml}" />
  87.             <arg value="-S" /><!-- S指定res目录,生成对应的ID,可多个-->
  88.             <arg value="${resource-dir}" />
  89.             <arg value="-S" />
  90.             <arg value="${library-dir}/res" /><!-- 注意点:同时需要调用Library的res-->
  91.             <arg value="-S" />
  92.             <arg value="${library-dir2}/res" /><!-- 注意点:同时需要调用Library的res-->
  93.             <arg value="-I" /><!-- I指定android包的位置-->
  94.             <arg value="${android-jar}" />
  95.             <arg value="--auto-add-overlay" /> <!-- 这个重要,覆盖资源,不然报错-->
  96.         </exec>
  97.         <!-- 根据库应用中的资源文件生成R.java文件 -->
  98.         <exec executable="${android-aapt}" failonerror="true">
  99.             <arg value="package" />
  100.             <arg value="-m" />
  101.             <arg value="--auto-add-overlay" />
  102.             <arg value="-J" />
  103.             <arg value="${outdir-gen}" />
  104.             <arg value="-M" />
  105.             <arg value="${library-dir}/AndroidManifest.xml" /><!-- 库应用的manifest-->
  106.             <arg value="-S" />
  107.             <arg value="${resource-dir}" />
  108.             <arg value="-S" />
  109.             <arg value="${library-dir}/res" />
  110.             <arg value="-I" />
  111.             <arg value="${android-jar}" />
  112.         </exec>
  113.         <!-- 根据库应用中的资源文件生成R.java文件 -->
  114.         <exec executable="${android-aapt}" failonerror="true">
  115.             <arg value="package" />
  116.             <arg value="-m" />
  117.             <arg value="--auto-add-overlay" />
  118.             <arg value="-J" />
  119.             <arg value="${outdir-gen}" />
  120.             <arg value="-M" />
  121.             <arg value="${library-dir2}/AndroidManifest.xml" /><!-- 库应用的manifest-->
  122.             <arg value="-S" />
  123.             <arg value="${resource-dir}" />
  124.             <arg value="-S" />
  125.             <arg value="${library-dir2}/res" />
  126.             <arg value="-I" />
  127.             <arg value="${android-jar}" />
  128.         </exec>
  129.     </target>
  130.     <!-- 将工程及库应用中的java源文件编译成class文件 -->
  131.     <target name="compile" depends="GenRJAVA">
  132.         <echo>Compiling java source code...</echo>
  133.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}">
  134.             <src path="${library-dir}/src" /><!-- 库应用源码 -->
  135.             <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下 -->
  136.             <classpath>
  137.                 <fileset dir="${library-dir}/libs" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译 -->
  138.             </classpath>
  139.         </javac>
  140.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}">
  141.             <src path="${library-dir2}/src" /><!-- 库应用源码 -->
  142.             <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下 -->
  143.             <classpath>
  144.                 <fileset dir="${library-dir2}/libs" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译 -->
  145.             </classpath>
  146.         </javac>
  147.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}">
  148.             <src path="${project.home}/src" /><!-- 工程源码-->
  149.             <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下 -->
  150.             <classpath>
  151.                 <fileset dir="${library}" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译 -->
  152.             </classpath>
  153.         </javac>
  154.     </target>
  155.     <!-- 将.class文件转化成.dex文件 -->
  156.     <target name="dex" depends="compile">
  157.         <echo>Converting compiled files and external libraries into ${outdir-dx}test.dex...</echo>
  158.         <exec executable="${android-dx}" failonerror="true">
  159.             <arg value="--dex" />
  160.             <arg value="--output=${dex-ospath}" /><!-- 输出 -->
  161.             <arg path="${outdir-classes}" /><!-- classes文件位置 -->
  162.             <arg value="${library}" /> <!-- 把libs下所有jar打包 -->
  163.         </exec>
  164.     </target>
  165.     <!-- 将资源文件放进输出目录 -->
  166.     <target name="package-res-and-assets">
  167.         <echo>Packaging resources and assets...</echo>
  168.         <exec executable="${android-aapt}" failonerror="true">
  169.             <arg value="package" />
  170.             <arg value="-f" /><!-- 资源覆盖重写 -->
  171.             <arg value="-M" />
  172.             <arg value="${manifest-xml}" />
  173.             <arg value="-S" />
  174.             <arg value="${resource-dir}" />
  175.             <arg value="-S"/>
  176.             <arg value="${library-dir}/res"/>
  177.             <arg value="-S"/>
  178.             <arg value="${library-dir2}/res"/>
  179.             <arg value="-A" /><!-- asset目录也打包 -->
  180.             <arg value="${asset-dir}" />
  181.             <arg value="-I" />
  182.             <arg value="${android-jar}" />
  183.             <arg value="-F" /><!-- 输出资源压缩包 -->
  184.             <arg value="${resources-package}" />
  185.             <arg value="--auto-add-overlay" />
  186.         </exec>
  187.     </target>
  188.     <!-- 打包成未签证的apk -->
  189.     <target name="package" depends="dex,package-res-and-assets">
  190.         <echo>Packaging unsigned apk for release...</echo>
  191.         <exec executable="${android-apkbuilder}" >
  192.             <arg value="${out-unsigned-package-ospath}" /><!-- 输出 -->
  193.             <arg value="-u" /><!-- u指创建未签名的包-->
  194.             <arg value="-z" /><!-- 资源压缩包 -->
  195.             <arg value="${resources-package-ospath}" />
  196.             <arg value="-f" /><!-- dex文件 -->
  197.             <arg value="${dex-ospath}" />
  198.             <arg value="-nf"/><!-- 把libs下的so库打包 -->
  199.             <arg value="${library}" />
  200.         </exec>
  201.         <echo>It will need to be signed with jarsigner before being published.</echo>
  202.     </target>
  203.     <!-- 对apk进行签证 -->
  204.     <target name="jarsigner" depends="package">
  205.         <echo>Packaging signed apk for release...</echo>
  206.         <exec executable="${android-jarsigner}" failonerror="true">
  207.             <arg value="-keystore" />
  208.             <arg value="${keystore-file}" />
  209.             <arg value="-storepass" />
  210.             <arg value="111111" /><!-- 验证密钥完整性的口令,创建时建立的 -->
  211.             <arg value="-keypass" />
  212.             <arg value="111111" /> <!-- 专用密钥的口令,就是key密码 -->
  213.             <arg value="-signedjar" />
  214.             <arg value="${out-signed-package-ospath}" /><!-- 输出 -->
  215.             <arg value="${out-unsigned-package-ospath}" /><!-- 未签名的apk -->
  216.             <!-- 不要忘了证书的别名 -->
  217.             <arg value="kunshan" />
  218.         </exec>
  219.     </target>
  220.     <!-- 优化 -->
  221.     <target name="optimize-app" depends="jarsigner">
  222.       <echo> optimizing the application...</echo>
  223.       <exec executable="${android-zipalign}">
  224.         <arg value="-v" />
  225.         <arg value="-f" />
  226.         <arg value="4" />
  227.         <arg value="${out-signed-package-ospath}" />
  228.         <arg value="${zipalign-signed-package}" />
  229.      </exec>
  230.     </target>
  231.     <!-- 发布 -->
  232.     <target name="release" depends="optimize-app">
  233.         <!-- 删除未签证apk -->
  234.         <delete file="${out-unsigned-package-ospath}" />
  235.         <echo>APK is released. path:${out-signed-package-ospath}</echo>
  236.         <copy file="${out-signed-package-ospath}" tofile="${outdir-package}"></copy>
  237.         <echo>APK is copy to path:${outdir-package}</echo>
  238.     </target>
  239. </project>


=========解析=========
其中动态库so文件目录我是没用到了,不过第三方library我是用到了两个,所以定义了两个,注意,我们的两个library里面有依赖关系,
library-dir2依赖library-dir

重点1,资源文件打包:
根据工程中的资源文件生成R.java文件,我会把library中的res和library2中的res都打包到我的最终目录中。(具体自己看代码)

重点2,src文件打包:
同样的道理,复制两份,自己看代码应该看得明白。

重点3:这时我们来运行ant命令来打包了,打包资源文件的时候很容易打包,没有报错,但是打包src文件的时候,会提示找不到BuildConfig.java
原来我使用了ZI-master,代码里面会使用到gen下的BuildConfig.java,但是我们的ant命令并没有生成BuildConfig.java,只能生成R.java。
好蛋疼,网上搜到了一个BuildConfig模板的解决方案,但是不好用,于是我想到了一个复制的方法,手动写死把代码复制进去。

到了这里,3大难点解析完毕了。大家有什么疑问欢迎在此跟帖,有问必答~



[url=http://www.phpwind.com]phpwind[/url]
离线太史慈

发帖
777
金币
626
威望
556
只看该作者 沙发  发表于: 2013-08-30
今天回看了一下这个打包,发现生成R.java文件的时候写错了,类库里面应该也要把主程序的res引用,不然程序会报错的。
本部分内容设定了隐藏,需要回复后才能看到


通过使用aapt的参数  --extra-packages. 其参数的说明如下:generate R.java for libraries. Separate libraries with ':'.
所以可以将上面的ant命令合并成一个。


其他博客里面查到的,据说~~据说而已,我没试出来,大家可以试试~
[url=http://www.phpwind.com]phpwind[/url]
快速回复
限100 字节
如果您在写长篇帖子又不马上发表,建议存为草稿
 
提到某人:
选择好友
上一个 下一个