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

前部分是转载,此文帮了我的大忙,转此以备后用,之前一直用第一种方法,能打出来包也能成功安装,但启动就会报错,原因是找不到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.

<!-- 生成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>

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

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

<!-- 生成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="${dest-dir}\AndroidManifest.xml" />
            <arg value="-S" />
            <arg value="${resource-dir}" />
            <arg value="-S" />
            <arg value="${library-dir}" />
            <arg value="--extra-packages" />
            <arg value="cn.test" /><!-- Library Project的包名 -->            
            <arg value="-A" />
            <arg value="${asset-dir}" />
            <arg value="-I" />
            <arg value="${android-jar}" />
        </exec>

----结束转>

完整打包的xml,我这里有4个library project
<?xml version="1.0" encoding="UTF-8"?>
<project name="projectname" default="release" basedir=".">
	<property file="build.properties"/>
    <property file="ProjectHome.properties"/>
    <!-- 生成R文件的相对目录 -->
    <property name="outdir-gen" value="gen" />
    <!-- 编译后的文件放置目录 -->
    <property name="outdir-bin" value="bin" />
    
    <!-- 输出目录 -->
	<property name="outdir" value="dest" />
    <!-- 清单文件 -->
    <property name="manifest-xml" value="AndroidManifest.xml" />
    <!-- 源文件目录 -->
    <property name="resource-dir" value="res" />
    <property name="asset-dir" value="assets" />
    <property name="sidno" value="0" />
    <!-- 资源文件目录 -->
    <property name="drawable-dir" value="${resource-dir}/drawable" />
    <property name="drawable-hdpi-dir" value="${resource-dir}/drawable-hdpi"/>
    <property name="drawable-ldpi-dir" value="${resource-dir}/drawable-ldpi"/>
    <property name="drawable-mdpi-dir" value="${resource-dir}/drawable-mdpi"/>
    <property name="drawable-xhdpi-dir" value="${resource-dir}/drawable-xhdpi"/>
    <property name="drawable-zh-rCN-dir" value="${resource-dir}/drawable-zh-rCN"/>
    <!-- java源文件目录 -->
    <property name="srcdir" value="src" />
    <property name="srcdir-ospath" value="${basedir}\${srcdir}" />
    <!-- 动态库so文件目录 -->
    <property name="library" value="libs" />
    <property name="library-ospath" value="${basedir}\${library}" />
    <!-- 第三方library -->
    <property name="library-dir1" value="${library1}" />
    <property name="library-dir2" value="${library2}" />
    <property name="library-dir3" value="${library3}" />
    <property name="library-dir4" value="${library4}" />
    <!-- 外部类库所在目录 -->
    <property name="external-lib" value="lib" />
    <property name="external-lib-ospath" value="${basedir}\${external-lib}" />
    <!-- 生成class目录 -->
    <property name="outdir-classes" value="${outdir-bin}/classes" />
    <property name="outdir-classes-ospath" value="${basedir}\${outdir-classes}" />
    <!-- classes.dex相关变量 -->
    <property name="dex-file" value="classes.dex" />
    <property name="dex-path" value="${outdir-bin}/${dex-file}" />
    <property name="dex-ospath" value="${basedir}\${dex-path}" />
    <!-- 编译后的文件放置目录 -->
	<property name="outdir-bin" value="bin" />
    <!-- 经过aapt生成的资源包文件 -->
    <property name="resources-package" value="${outdir-bin}\resources.ap_" />
    <property name="resources-package-ospath" value="${basedir}\${resources-package}" />
    <!-- 未认证apk包 -->
    <property name="out-unsigned-package" value="${outdir}\${ant.project.name}-unsigned_${sidno}.apk" />
    <property name="out-unsigned-package-ospath" value="${basedir}\${out-unsigned-package}" />
    <!-- 证书文件 -->
    <property name="keystore-file" value="${keystore}" />
    <!-- 已认证apk包 -->
    <property name="out-signed-package" value="${outdir}/${ant.project.name}_SID_${sidno}.apk" />
    <property name="out-signed-package-ospath" value="${basedir}\${out-signed-package}" />
    <!-- 已优化apk包 -->
    <property name="zipalign-signed-package" value="${basedir}\${outdir}/${ant.project.name}_SID_${sidno}_zipalign.apk" />
    <!-- 输出路径的apk包 -->
    <property name="outdir-package" value="${basedir}\${outdir}/${ant.project.name}.apk" />
    
    	<!-- Tools -->
	<condition property="aapt" value="${android.tools}/aapt.exe" else="${android.tools}/aapt">
		<os family="windows" />
	</condition>
	<condition property="zipalign" value="${apk.tools}/zipalign.exe" else="${apk.tools}/zipalign">
		<os family="windows" />
	</condition>
	<condition property="jarsigner" value="${jdk.home}/bin/jarsigner.exe" else="${jdk.home}/bin/jarsigner">
		<os family="windows" />
	</condition>
	<condition property="aidl" value="${android.tools}/aidl.exe" else="${android.tools}/aidl">
		<os family="windows" />
	</condition>
	<condition property="adb" value="${apk.tools}/adb.exe" else="${apk.tools}/adb">
		<os family="windows" />
	</condition>
	<condition property="dx" value="${android.tools}/dx.bat" else="${android.tools}/dx">
		<os family="windows" />
	</condition>
	<condition property="apk-builder" value="${apk.tools}/apkbuilder.bat" else="${apk.tools}/apkbuilder">
		<os family="windows" />
	</condition>
	
	<condition property="java" value="${jdk.home}/bin/java.exe" else="${jdk.home}/bin/java">
		<os family="windows" />
	</condition>
    <!-- 初始化工作 -->
    <target name="init">
        <echo>Initializing all output directories...</echo>
        <delete dir="${outdir-bin}" />
        <delete dir="${outdir}" /> 
        <delete dir="${outdir-gen}" />
        <delete dir="${library-dir1}/bin" />
        <delete dir="${library-dir2}/bin" />
        <delete dir="${library-dir3}/bin" />
        <delete dir="${library-dir4}/bin" /> 
        <delete dir="${library-dir1}/gen" />
        <delete dir="${library-dir2}/gen" />
        <delete dir="${library-dir3}/gen" />
        <delete dir="${library-dir4}/gen" /> 
        <mkdir dir="${outdir}" />  
        <mkdir dir="${outdir-gen}" />
        <mkdir dir="${outdir-bin}" />
        <mkdir dir="${library-dir1}/bin" />
        <mkdir dir="${library-dir2}/bin" />
        <mkdir dir="${library-dir3}/bin" />
        <mkdir dir="${library-dir4}/bin" />
        <mkdir dir="${library-dir1}/gen" />
        <mkdir dir="${library-dir2}/gen" />
        <mkdir dir="${library-dir3}/gen" />
        <mkdir dir="${library-dir4}/gen" />
        
        <mkdir dir="${outdir-classes}" />
    </target> 
    <!-- 根据工程中的资源文件生成R.java文件 -->
     <target name="GenRJAVA" depends="init">
        <echo>Generating R.java / Manifest.java from the resources...</echo>

        <!-- 根据库应用中的资源文件生成R.java文件 -->
        <exec executable="${aapt}" failοnerrοr="true" >

            <arg value="package" /><!-- package表示打包-->
            <arg value="-m" /><!--m,J,gen表示创建包名的目录和R.java到gen目录下 -->
            <arg value="-J" />
            <arg value="${outdir-gen}" />
            <arg value="-M" /><!-- M指定AndroidManifest.xml文件-->
            <arg value="${manifest-xml}" />
            <arg value="-S" /><!-- S指定res目录,生成对应的ID,可多个-->
            <arg value="${resource-dir}" />
            <arg value="-S" />
            <arg value="${library-dir1}/res" /> <!--  注意点:同时需要调用Library的res-->
            <arg value="-S" />
            <arg value="${library-dir2}/res" /> 
            <arg value="-S" />
            <arg value="${library-dir3}/res" />
            <arg value="-S" />
            <arg value="${library-dir4}/res" />
            <arg value="--extra-packages" />
            <arg value="librarypackagename1:librarypackagename2:librarypackagename3:librarypackagename4" />          
            <arg value="-I" /><!-- I指定android包的位置-->
            <arg value="${android-jar23}" />
            <arg value="--auto-add-overlay" /> <!-- 这个重要,覆盖资源,不然报错-->


        </exec>
    </target>
    
    <!-- 将工程及库应用中的java源文件编译成class文件 -->
    <target name="compile" depends="GenRJAVA">
        <echo>Compiling java source code...</echo>
        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar23}">
            <src path="${library-dir1}/src" /><!-- 库应用源码 -->
            <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下 -->
            <classpath>
                <fileset dir="${library-dir1}/libs" includes="*.jar" /><!-- 第三方jar包需要引用,用于辅助编译-->
            </classpath> 
        </javac>
        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar30}">
            <src path="${library-dir2}/src" />
            <src path="${outdir-gen}" />
            <classpath>
                <fileset dir="${library-dir2}/libs" includes="*.jar" /> 
            </classpath>
        </javac>
        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar41}">
            <src path="${library-dir3}/src" />
            <src path="${outdir-gen}" />
            <classpath>
                <fileset dir="${library-dir3}/libs" includes="*.jar" /> 
            </classpath>
        </javac>
        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar43}">
            <src path="${library-dir4}/src" />
            <src path="${outdir-gen}" />
            <classpath>
                <fileset dir="${library-dir4}/libs" includes="*.jar" /> 
            </classpath>
         </javac>
 		
        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar23}">                
            <src path="${srcdir}" /><!-- 工程src目录-->
            <src path="${outdir-gen}" /><!-- 工程gen目录 -->
            <classpath >
				<fileset dir="${library-ospath}" includes="*.jar"/>
			</classpath>
        </javac>
          
    </target>
    <!-- 将.class文件转化成.dex文件 -->
    <target name="dex" depends="compile">
        <echo>Converting compiled files and external libraries into ${outdir-dx}test.dex...</echo>
        <exec executable="${dx}" failοnerrοr="true">
            <arg value="--dex" />
            <arg value="--output=${dex-ospath}" /><!-- 输出 -->
            <arg path="${outdir-classes-ospath}" /><!-- classes文件位置 -->
            <arg value="${library-ospath}" /> <!-- 把libs下所有jar打包 -->
        </exec>
    </target>
    <!-- 将资源文件放进输出目录 -->
    <target name="package-res-and-assets">
        <echo>Packaging resources and assets...</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-dir1}/res"/>
            <arg value="-S"/>
            <arg value="${library-dir2}/res"/>
            <arg value="-S"/>
            <arg value="${library-dir3}/res"/>
            <arg value="-S"/>
            <arg value="${library-dir4}/res"/>
            <arg value="-A" /><!-- asset目录也打包 -->
            <arg value="${asset-dir}" />
            <arg value="-I" />
            <arg value="${android-jar23}" />
            <arg value="-F" /><!-- 输出资源压缩包 -->
            <arg value="${resources-package}" />
            <arg value="--auto-add-overlay" />
        </exec>
    </target>
     <target name="package-res" depends="dex">
		<available file="${asset-dir}" type="dir" property="res-target" value="and-assets" />
		<property name="res-target" value="no-assets" />
		<antcall target="package-res-${res-target}" />
	</target>
    <!-- 打包成未签证的apk -->
    <target name="package" depends="package-res">
        <echo>Packaging unsigned apk for release...</echo>
        <exec executable="${apk-builder}" >
            <arg value="${out-unsigned-package-ospath}" /><!-- 输出 -->
            <arg value="-u" /><!-- u指创建未签名的包-->
            <arg value="-z" /><!-- 资源压缩包 -->
            <arg value="${resources-package-ospath}" />
            <arg value="-f" /><!-- dex文件 -->
            <arg value="${dex-ospath}" />
            <arg value="-rf" />
			<arg value="${srcdir-ospath}" />
            <arg value="-nf"/><!-- 把libs下的so库打包 -->
            <arg value="${library-ospath}" />
        </exec>
        <echo>It will need to be signed with jarsigner before being published.</echo>
    </target>
    
   
    	<!--进行签名-->
	<target name="jarsigner" depends="package">
		<echo message="准备进行签名" />
		<exec executable="${jarsigner}" failοnerrοr="true">
			<arg value="-storepass" />
			<arg value="${password}" />
			<arg value="-keystore" />
			<arg value="${basedir}\${keystore}" />
			<arg value="-signedjar" />
			<arg value="${out-signed-package-ospath}" />
			<arg value="${out-unsigned-package-ospath}" />
			<arg value="passward" />
		</exec>
		<echo message="签名成功" />
	</target>
    <!-- 优化 -->
    <target name="optimize-app" depends="jarsigner">
      <echo> optimizing the application...</echo>
      <exec executable="${zipalign}">
        <arg value="-v" />
        <arg value="-f" />
        <arg value="4" />
        <arg value="${out-signed-package-ospath}" />
        <arg value="${zipalign-signed-package}" />
     </exec>
    </target>
    <!-- 发布 -->
    <target name="release" depends="optimize-app">
        <!-- 删除未签证apk -->
        <delete file="${out-unsigned-package-ospath}" />
        <echo>APK is released. path:${out-signed-package-ospath}</echo>
        <copy file="${out-signed-package-ospath}" tofile="${outdir-package}"></copy>
        <echo>APK is copy to path:${outdir-package}</echo>
    </target>
</project

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值