Android通过ant脚本打包带Library project的方法

时间:2022-02-02 08:47:59

前部分是转载,此文帮了我的大忙,转此以备后用,之前一直用第一种方法,能打出来包也能成功安装,但启动就会报错,原因是找不到library project的资源,根据此贴修改成使用第二种方法,解决问题~棒

下方我会贴出我的完整build.xml

<转----

     对于Android程序打包,一般可以通过Eclipse进行打包.但如果一个程序需要发布到多个不同渠道的时候,就需要用到Ant脚本辅助打包了.

     但网上很多的android程序(app project)ant脚本一般都只针对一个项目,对于引用了library project的没有什么有用的资料.

     如果直接按照一个项目的方式去打包,要不会不能成功打进去资源文件,要不不能成功的生成R.java文件,从而导致引用资源报错抛异常.

     经过查找国外网站和有个cp技术的提醒,可以有两种方式实现.

     (1)cp技术的方法,对于app project 和 library project,各执行一次aapt命令,但各指向不同的manifest文件,让其能读取manifest中的package信息,并生成对应的package下的R.java文件.这样的问题是两个R.java会生成app project和 library project的所有的资源id.

[html]  view plain copy Android通过ant脚本打包带Library project的方法 Android通过ant脚本打包带Library project的方法
  1. <!-- 生成app project的 R.java-->   
  2. <exec  
  3.             executable="${aapt}"  
  4.             failonerror="true" >  
  5.             <arg value="package" />  
  6.             <arg value="-m" />              
  7.             <arg value="--auto-add-overlay" />  
  8.             <arg value="-J" />  
  9.             <arg value="${out-dir-gen}" />  
  10.             <arg value="-M" />  
  11.             <arg value="${destdir}\AndroidManifest.xml" />  
  12.             <arg value="-S" />  
  13.             <arg value="${resource-dir}" />  
  14.             <arg value="-S" />  
  15.             <arg value="${library-dir}" />            
  16.             <arg value="-A" />  
  17.             <arg value="${asset-dir}" />  
  18.             <arg value="-I" />  
  19.             <arg value="${android-jar}" />  
  20.         </exec>  
  21. <!-- 生成liibrary project的 R.java-->   
  22.  <exec  
  23.             executable="${aapt}"  
  24.             failonerror="true" >  
  25.             <arg value="package" />  
  26.             <arg value="-m" />              
  27.             <arg value="--auto-add-overlay" />  
  28.             <arg value="-J" />  
  29.             <arg value="${out-dir-gen}" />  
  30.             <arg value="-M" />  
  31.             <arg value="${library-dir}\AndroidManifest.xml" />  
  32.             <arg value="-S" />  
  33.             <arg value="${resource-dir}" />  
  34.             <arg value="-S" />  
  35.             <arg value="${library-dir}" />            
  36.             <arg value="-A" />  
  37.             <arg value="${asset-dir}" />  
  38.             <arg value="-I" />  
  39.             <arg value="${android-jar}" />  
  40.         </exec>  

 (2)通过使用aapt的参数  --extra-packages. 其参数的说明如下:generate R.java for libraries. Separate libraries with ':'.

所以可以将上面的ant命令合并成一个:

[html]  view plain copy Android通过ant脚本打包带Library project的方法 Android通过ant脚本打包带Library project的方法
  1. <!-- 生成liibrary project的 R.java-->   
  2.  <exec  
  3.             executable="${aapt}"  
  4.             failonerror="true" >  
  5.             <arg value="package" />  
  6.             <arg value="-m" />              
  7.             <arg value="--auto-add-overlay" />  
  8.             <arg value="-J" />  
  9.             <arg value="${out-dir-gen}" />  
  10.             <arg value="-M" />  
  11.             <arg value="${dest-dir}\AndroidManifest.xml" />  
  12.             <arg value="-S" />  
  13.             <arg value="${resource-dir}" />  
  14.             <arg value="-S" />  
  15.             <arg value="${library-dir}" />  
  16.             <arg value="--extra-packages" />  
  17.             <arg value="cn.test" /><!-- Library Project的包名 -->              
  18.             <arg value="-A" />  
  19.             <arg value="${asset-dir}" />  
  20.             <arg value="-I" />  
  21.             <arg value="${android-jar}" />  
  22.         </exec>  

----结束转>

完整打包的xml,我这里有4个library project
[html]  view plain copy Android通过ant脚本打包带Library project的方法 Android通过ant脚本打包带Library project的方法
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <project name="projectname" default="release" basedir=".">  
  3.     <property file="build.properties"/>  
  4.     <property file="ProjectHome.properties"/>  
  5.     <!-- 生成R文件的相对目录 -->  
  6.     <property name="outdir-gen" value="gen" />  
  7.     <!-- 编译后的文件放置目录 -->  
  8.     <property name="outdir-bin" value="bin" />  
  9.       
  10.     <!-- 输出目录 -->  
  11.     <property name="outdir" value="dest" />  
  12.     <!-- 清单文件 -->  
  13.     <property name="manifest-xml" value="AndroidManifest.xml" />  
  14.     <!-- 源文件目录 -->  
  15.     <property name="resource-dir" value="res" />  
  16.     <property name="asset-dir" value="assets" />  
  17.     <property name="sidno" value="0" />  
  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-xhdpi-dir" value="${resource-dir}/drawable-xhdpi"/>  
  24.     <property name="drawable-zh-rCN-dir" value="${resource-dir}/drawable-zh-rCN"/>  
  25.     <!-- java源文件目录 -->  
  26.     <property name="srcdir" value="src" />  
  27.     <property name="srcdir-ospath" value="${basedir}\${srcdir}" />  
  28.     <!-- 动态库so文件目录 -->  
  29.     <property name="library" value="libs" />  
  30.     <property name="library-ospath" value="${basedir}\${library}" />  
  31.     <!-- 第三方library -->  
  32.     <property name="library-dir1" value="${library1}" />  
  33.     <property name="library-dir2" value="${library2}" />  
  34.     <property name="library-dir3" value="${library3}" />  
  35.     <property name="library-dir4" value="${library4}" />  
  36.     <!-- 外部类库所在目录 -->  
  37.     <property name="external-lib" value="lib" />  
  38.     <property name="external-lib-ospath" value="${basedir}\${external-lib}" />  
  39.     <!-- 生成class目录 -->  
  40.     <property name="outdir-classes" value="${outdir-bin}/classes" />  
  41.     <property name="outdir-classes-ospath" value="${basedir}\${outdir-classes}" />  
  42.     <!-- classes.dex相关变量 -->  
  43.     <property name="dex-file" value="classes.dex" />  
  44.     <property name="dex-path" value="${outdir-bin}/${dex-file}" />  
  45.     <property name="dex-ospath" value="${basedir}\${dex-path}" />  
  46.     <!-- 编译后的文件放置目录 -->  
  47.     <property name="outdir-bin" value="bin" />  
  48.     <!-- 经过aapt生成的资源包文件 -->  
  49.     <property name="resources-package" value="${outdir-bin}\resources.ap_" />  
  50.     <property name="resources-package-ospath" value="${basedir}\${resources-package}" />  
  51.     <!-- 未认证apk包 -->  
  52.     <property name="out-unsigned-package" value="${outdir}\${ant.project.name}-unsigned_${sidno}.apk" />  
  53.     <property name="out-unsigned-package-ospath" value="${basedir}\${out-unsigned-package}" />  
  54.     <!-- 证书文件 -->  
  55.     <property name="keystore-file" value="${keystore}" />  
  56.     <!-- 已认证apk包 -->  
  57.     <property name="out-signed-package" value="${outdir}/${ant.project.name}_SID_${sidno}.apk" />  
  58.     <property name="out-signed-package-ospath" value="${basedir}\${out-signed-package}" />  
  59.     <!-- 已优化apk包 -->  
  60.     <property name="zipalign-signed-package" value="${basedir}\${outdir}/${ant.project.name}_SID_${sidno}_zipalign.apk" />  
  61.     <!-- 输出路径的apk包 -->  
  62.     <property name="outdir-package" value="${basedir}\${outdir}/${ant.project.name}.apk" />  
  63.       
  64.         <!-- Tools -->  
  65.     <condition property="aapt" value="${android.tools}/aapt.exe" else="${android.tools}/aapt">  
  66.         <os family="windows" />  
  67.     </condition>  
  68.     <condition property="zipalign" value="${apk.tools}/zipalign.exe" else="${apk.tools}/zipalign">  
  69.         <os family="windows" />  
  70.     </condition>  
  71.     <condition property="jarsigner" value="${jdk.home}/bin/jarsigner.exe" else="${jdk.home}/bin/jarsigner">  
  72.         <os family="windows" />  
  73.     </condition>  
  74.     <condition property="aidl" value="${android.tools}/aidl.exe" else="${android.tools}/aidl">  
  75.         <os family="windows" />  
  76.     </condition>  
  77.     <condition property="adb" value="${apk.tools}/adb.exe" else="${apk.tools}/adb">  
  78.         <os family="windows" />  
  79.     </condition>  
  80.     <condition property="dx" value="${android.tools}/dx.bat" else="${android.tools}/dx">  
  81.         <os family="windows" />  
  82.     </condition>  
  83.     <condition property="apk-builder" value="${apk.tools}/apkbuilder.bat" else="${apk.tools}/apkbuilder">  
  84.         <os family="windows" />  
  85.     </condition>  
  86.       
  87.     <condition property="java" value="${jdk.home}/bin/java.exe" else="${jdk.home}/bin/java">  
  88.         <os family="windows" />  
  89.     </condition>  
  90.     <!-- 初始化工作 -->  
  91.     <target name="init">  
  92.         <echo>Initializing all output directories...</echo>  
  93.         <delete dir="${outdir-bin}" />  
  94.         <delete dir="${outdir}" />   
  95.         <delete dir="${outdir-gen}" />  
  96.         <delete dir="${library-dir1}/bin" />  
  97.         <delete dir="${library-dir2}/bin" />  
  98.         <delete dir="${library-dir3}/bin" />  
  99.         <delete dir="${library-dir4}/bin" />   
  100.         <delete dir="${library-dir1}/gen" />  
  101.         <delete dir="${library-dir2}/gen" />  
  102.         <delete dir="${library-dir3}/gen" />  
  103.         <delete dir="${library-dir4}/gen" />   
  104.         <mkdir dir="${outdir}" />    
  105.         <mkdir dir="${outdir-gen}" />  
  106.         <mkdir dir="${outdir-bin}" />  
  107.         <mkdir dir="${library-dir1}/bin" />  
  108.         <mkdir dir="${library-dir2}/bin" />  
  109.         <mkdir dir="${library-dir3}/bin" />  
  110.         <mkdir dir="${library-dir4}/bin" />  
  111.         <mkdir dir="${library-dir1}/gen" />  
  112.         <mkdir dir="${library-dir2}/gen" />  
  113.         <mkdir dir="${library-dir3}/gen" />  
  114.         <mkdir dir="${library-dir4}/gen" />  
  115.           
  116.         <mkdir dir="${outdir-classes}" />  
  117.     </target>   
  118.     <!-- 根据工程中的资源文件生成R.java文件 -->  
  119.      <target name="GenRJAVA" depends="init">  
  120.         <echo>Generating R.java / Manifest.java from the resources...</echo>  
  121.   
  122.         <!-- 根据库应用中的资源文件生成R.java文件 -->  
  123.         <exec executable="${aapt}" failonerror="true" >  
  124.   
  125.             <arg value="package" /><!-- package表示打包-->  
  126.             <arg value="-m" /><!--m,J,gen表示创建包名的目录和R.java到gen目录下 -->  
  127.             <arg value="-J" />  
  128.             <arg value="${outdir-gen}" />  
  129.             <arg value="-M" /><!-- M指定AndroidManifest.xml文件-->  
  130.             <arg value="${manifest-xml}" />  
  131.             <arg value="-S" /><!-- S指定res目录,生成对应的ID,可多个-->  
  132.             <arg value="${resource-dir}" />  
  133.             <arg value="-S" />  
  134.             <arg value="${library-dir1}/res" /> <!--  注意点:同时需要调用Library的res-->  
  135.             <arg value="-S" />  
  136.             <arg value="${library-dir2}/res" />   
  137.             <arg value="-S" />  
  138.             <arg value="${library-dir3}/res" />  
  139.             <arg value="-S" />  
  140.             <arg value="${library-dir4}/res" />  
  141.             <arg value="--extra-packages" />  
  142.             <arg value="librarypackagename1:librarypackagename2:librarypackagename3:librarypackagename4" />            
  143.             <arg value="-I" /><!-- I指定android包的位置-->  
  144.             <arg value="${android-jar23}" />  
  145.             <arg value="--auto-add-overlay" /> <!-- 这个重要,覆盖资源,不然报错-->  
  146.   
  147.   
  148.         </exec>  
  149.     </target>  
  150.       
  151.     <!-- 将工程及库应用中的java源文件编译成class文件 -->  
  152.     <target name="compile" depends="GenRJAVA">  
  153.         <echo>Compiling java source code...</echo>  
  154.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar23}">  
  155.             <src path="${library-dir1}/src" /><!-- 库应用源码 -->  
  156.             <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下 -->  
  157.             <classpath>  
  158.                 <fileset dir="${library-dir1}/libs" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译-->  
  159.             </classpath>   
  160.         </javac>  
  161.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar30}">  
  162.             <src path="${library-dir2}/src" />  
  163.             <src path="${outdir-gen}" />  
  164.             <classpath>  
  165.                 <fileset dir="${library-dir2}/libs" includes="*.jar" />   
  166.             </classpath>  
  167.         </javac>  
  168.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar41}">  
  169.             <src path="${library-dir3}/src" />  
  170.             <src path="${outdir-gen}" />  
  171.             <classpath>  
  172.                 <fileset dir="${library-dir3}/libs" includes="*.jar" />   
  173.             </classpath>  
  174.         </javac>  
  175.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar43}">  
  176.             <src path="${library-dir4}/src" />  
  177.             <src path="${outdir-gen}" />  
  178.             <classpath>  
  179.                 <fileset dir="${library-dir4}/libs" includes="*.jar" />   
  180.             </classpath>  
  181.          </javac>  
  182.           
  183.         <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar23}">                  
  184.             <src path="${srcdir}" /><!-- 工程src目录-->  
  185.             <src path="${outdir-gen}" /><!-- 工程gen目录 -->  
  186.             <classpath >  
  187.                 <fileset dir="${library-ospath}" includes="*.jar"/>  
  188.             </classpath>  
  189.         </javac>  
  190.             
  191.     </target>  
  192.     <!-- 将.class文件转化成.dex文件 -->  
  193.     <target name="dex" depends="compile">  
  194.         <echo>Converting compiled files and external libraries into ${outdir-dx}test.dex...</echo>  
  195.         <exec executable="${dx}" failonerror="true">  
  196.             <arg value="--dex" />  
  197.             <arg value="--output=${dex-ospath}" /><!-- 输出 -->  
  198.             <arg path="${outdir-classes-ospath}" /><!-- classes文件位置 -->  
  199.             <arg value="${library-ospath}" /> <!-- 把libs下所有jar打包 -->  
  200.         </exec>  
  201.     </target>  
  202.     <!-- 将资源文件放进输出目录 -->  
  203.     <target name="package-res-and-assets">  
  204.         <echo>Packaging resources and assets...</echo>  
  205.         <exec executable="${aapt}" failonerror="true" >  
  206.             <arg value="package" />  
  207.             <arg value="-f" /><!-- 资源覆盖重写 -->  
  208.             <arg value="-M" />  
  209.             <arg value="${manifest-xml}" />  
  210.             <arg value="-S" />  
  211.             <arg value="${resource-dir}" />  
  212.             <arg value="-S"/>  
  213.             <arg value="${library-dir1}/res"/>  
  214.             <arg value="-S"/>  
  215.             <arg value="${library-dir2}/res"/>  
  216.             <arg value="-S"/>  
  217.             <arg value="${library-dir3}/res"/>  
  218.             <arg value="-S"/>  
  219.             <arg value="${library-dir4}/res"/>  
  220.             <arg value="-A" /><!-- asset目录也打包 -->  
  221.             <arg value="${asset-dir}" />  
  222.             <arg value="-I" />  
  223.             <arg value="${android-jar23}" />  
  224.             <arg value="-F" /><!-- 输出资源压缩包 -->  
  225.             <arg value="${resources-package}" />  
  226.             <arg value="--auto-add-overlay" />  
  227.         </exec>  
  228.     </target>  
  229.      <target name="package-res" depends="dex">  
  230.         <available file="${asset-dir}" type="dir" property="res-target" value="and-assets" />  
  231.         <property name="res-target" value="no-assets" />  
  232.         <antcall target="package-res-${res-target}" />  
  233.     </target>  
  234.     <!-- 打包成未签证的apk -->  
  235.     <target name="package" depends="package-res">  
  236.         <echo>Packaging unsigned apk for release...</echo>  
  237.         <exec executable="${apk-builder}" >  
  238.             <arg value="${out-unsigned-package-ospath}" /><!-- 输出 -->  
  239.             <arg value="-u" /><!-- u指创建未签名的包-->  
  240.             <arg value="-z" /><!-- 资源压缩包 -->  
  241.             <arg value="${resources-package-ospath}" />  
  242.             <arg value="-f" /><!-- dex文件 -->  
  243.             <arg value="${dex-ospath}" />  
  244.             <arg value="-rf" />  
  245.             <arg value="${srcdir-ospath}" />  
  246.             <arg value="-nf"/><!-- 把libs下的so库打包 -->  
  247.             <arg value="${library-ospath}" />  
  248.         </exec>  
  249.         <echo>It will need to be signed with jarsigner before being published.</echo>  
  250.     </target>  
  251.       
  252.      
  253.         <!--进行签名-->  
  254.     <target name="jarsigner" depends="package">  
  255.         <echo message="准备进行签名" />  
  256.         <exec executable="${jarsigner}" failonerror="true">  
  257.             <arg value="-storepass" />  
  258.             <arg value="${password}" />  
  259.             <arg value="-keystore" />  
  260.             <arg value="${basedir}\${keystore}" />  
  261.             <arg value="-signedjar" />  
  262.             <arg value="${out-signed-package-ospath}" />  
  263.             <arg value="${out-unsigned-package-ospath}" />  
  264.             <arg value="passward" />  
  265.         </exec>  
  266.         <echo message="签名成功" />  
  267.     </target>  
  268.     <!-- 优化 -->  
  269.     <target name="optimize-app" depends="jarsigner">  
  270.       <echo> optimizing the application...</echo>  
  271.       <exec executable="${zipalign}">  
  272.         <arg value="-v" />  
  273.         <arg value="-f" />  
  274.         <arg value="4" />  
  275.         <arg value="${out-signed-package-ospath}" />  
  276.         <arg value="${zipalign-signed-package}" />  
  277.      </exec>  
  278.     </target>  
  279.     <!-- 发布 -->  
  280.     <target name="release" depends="optimize-app">  
  281.         <!-- 删除未签证apk -->  
  282.         <delete file="${out-unsigned-package-ospath}" />  
  283.         <echo>APK is released. path:${out-signed-package-ospath}</echo>  
  284.         <copy file="${out-signed-package-ospath}" tofile="${outdir-package}"></copy>  
  285.         <echo>APK is copy to path:${outdir-package}</echo>  
  286.     </target>  
  287. </project<pre code_snippet_id="147550" snippet_file_name="blog_20140108_1_7792929"></pre>  
  288. <pre></pre>