ant自动打包apk(详细),引用到第三方工程类库以及里面的资源,修改包名和工程名

时间:2021-04-12 06:05:44

实现ant自动打包流程

1.进入项目的目录中,打开命令行窗口

android update project --name 项目名称 --path 项目的绝对路径

 

local.properties里面设置的是引用的参数,比如工具的路径、目录的路径、等等,

build.xml这里面是最主要的,通过引用local.properties中的参数来完成我们需求的操作。

我这里有现成的local.propertiesbuild.xml,可以直接复制,但是要使用的话还需要自己看代码,修改local.properties中的路径,设置成自己环境下的,也可以根据自己需求修改build.xml中的标签。

2.实现自动打包

我实现的打包流程:a.解压一个zip的压缩包,b.将压缩包中的图片、视频、Json数据、icon.png复制到指定的项目目录中c、修改项目的包名和app的名称d、打包成apk

下面是我的  local.properties   build.xml

Local.properties中的内容

#项目的路径

project.home=E:\\hoga_news\\holga-book

#

resource-dir=E:\\hoga_news\\holga-book\\res

#引用到第三方的工程类库

library-dir=E:\\hoga_news\\library_SlidingMenu

library-dir2=E:\\hoga_news\\FacebookSDK

#

delete-dir=E:\\hoga_news\\holga-book\\assets

#

values-dir=E:\\hoga_news\\holga-book\\res\\values

#生成的apk的名称的一部分

appName=offline-package

#

version=1.0.0

#生成的有签名的apk的路径

project.outdir=E:\\hoga_news\\offlineapks

#android.jar工具的路径

android-jar=E:\\sdk\\platforms\\android-22\\android.jar

#aapt.exe工具的路径

android-aapt=E:\\sdk\\platform-tools\\aapt.exe

#dx.bat工具的路径

android-dx=E:\\sdk\\platform-tools\\dx.bat

#sdklib.jar工具的路径

sdklib=E:\\sdk\\tools\\lib\\sdklib.jar

#jarsigner.exe工具路径

android-jarsigner=E:\\jdk\\bin\\jarsigner

#使用的key的路径

keystore-file=C:\\Users\\qingdong\\Desktop\\key\\lixianbao.key

#对齐工具路径

android-zipalign=E:\\sdk\\tools\\zipalign.exe

#生成优化后的apk的路径

success_apk_out_dir=C:\\Users\\qingdong\\Desktop\\offline_apks

#需要解压的压缩包的路径

zip-dir=C:\\Users\\qingdong\\Desktop\\ZIP

#SDK的路径

sdk.dir=E:\\sdk



build.xml 中的内容


<?xml version="1.0" encoding="UTF-8"?>

<project name="ProjectName" default="release" basedir=".">

 

    <property file="local.properties"/>

     <!--自定义时间戳 -->

     <tstamp>

     <format property="create-time" pattern="MM_dd_yyyy_HH_mm"/>

     </tstamp>

     <tstamp>

     <format property="pac-time" pattern="HHmm"/>

     </tstamp>

    

<target name="unzip-1" >

<!-- 解压文件到桌面的文件中-->

<unzip  dest="${zip-dir}">

<fileset dir="${zip-dir}">

         <include name="*.zip"/>

  </fileset>

  </unzip>

  <!-- 初始化文件夹,删除themeimages themenews  themevideos-->

  <delete dir="${delete-dir}/themeimages"/>

  <delete dir="${delete-dir}/themenews"/>

  <delete dir="${delete-dir}/themevideos"/>

  <mkdir dir="${delete-dir}/themeimages"/>

  <mkdir dir="${delete-dir}/themenews"/>

  <mkdir dir="${delete-dir}/themevideos"/>

</target>

<!-- 判断themeimages文件夹是否存在,存在就执行复制操作-->

<condition property="imgsdir.exist">

<and>

<available file="${zip-dir}/themeimages"/>

</and>

</condition>

<target name="imgs-dir-exist" if="imgsdir.exist" depends="unzip-1">

<echo>复制图片新闻的数据</echo>

<copy todir="${delete-dir}/themeimages">

<fileset dir="${zip-dir}/themeimages">

<include name="*.jpg"/>

<include name="icon.png"/>

</fileset>

</copy>

<copy todir="${delete-dir}/themenews">

<fileset dir="${zip-dir}/themeimages">

<include name="*.data"/>

</fileset>

</copy>   

</target>

<!-- 判断themevideos文件夹是否存在,存在就执行复制操作-->

<condition property="videosdir.exist">

<and>

<available file="${zip-dir}/themevideos"/>

</and>

</condition>

<target name="videos-dir-exist" if="videosdir.exist" depends="imgs-dir-exist">

<echo>复制视频的数据</echo>

<!-- <copy todir="${delete-dir}/themevideos">

<fileset dir="${zip-dir}/themevideos">

<include name="*.mp4"/>

<include name="icon.png"/>

<include name="icon.jpg"/>

</fileset>

</copy>

<copy todir="${delete-dir}/themenews">

<fileset dir="${zip-dir}/themevideos">

<include name="*.data"/>

</fileset>

</copy>    -->

</target>

<!-- 判断themenews文件夹是否存在,存在就执行复制操作-->

<condition property="newsdir.exist">

<and>

<available file="${zip-dir}/themenews"/>

</and>

</condition>

<target name="news-dir-exist" if="newsdir.exist" depends="videos-dir-exist">

<echo>复制纯新闻数据</echo>

<!-- <copy todir="${delete-dir}/themenews">

<fileset dir="${zip-dir}/themenews">

<include name="*.data"/>

</fileset>

</copy>     -->

</target>

<!-- 先删除icon,icon图片复制到drawable-nodpi-->

<target name="copy-icon" depends="news-dir-exist">

<delete file="${project.home}/res/drawable-nodpi/icon.png"/>

<delete file="${project.home}/res/drawable-nodpi/icon.jpg"/>

<copy file="${delete-dir}/themeimages/icon.png" todir="${project.home}/res/drawable-nodpi"/>

</target>

 

    <!-- ANT环境变量 -->

    <property environment="env" />

    <!-- 包名 项目名系列-->

    <property name="oldpac" value=""/>

    <property name="newpac" value=""/>

    <property name="oldpro" value=""/>

    <property name="newpro" value=""/>

    <!-- 生成R文件的相对目录-->

    <property name="outdir-gen" value="${project.home}/gen" />

    <!-- 编译后的文件放置目录 -->

    <property name="outdir-bin" value="${project.home}/bin" />

    <!-- 输出目录 -->

<property name="outdir" value="${project.outdir}" />

    <!-- 清单文件 -->

    <property name="manifest-xml" value="${project.home}/AndroidManifest.xml" />

    <!-- 源文件目录 -->

    <property name="resource-dir" value="res" />

    <property name="asset-dir" value="assets" />

    <!-- 资源文件目录 -->

    <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-nodpi-dir" value="${resource-dir}/drawable-nodpi"/>

    <property name="drawable-xhdpi-dir" value="${resource-dir}/drawable-xhdpi"/>

    <property name="drawable-xxhdpi-dir" value="${resource-dir}/drawable-xxhdpi"/>

    <!-- java源文件目录 -->

    <property name="srcdir" value="src" />

    <property name="srcdir-ospath" value="${project.home}/${srcdir}" />

    <!-- 动态库so文件目录-->

    <property name="library" value="${project.home}/libs" />

    <!-- 第三方library -->

    <property name="library-dir" value="${library-dir}" />

    <property name="library-dir2" value="${library-dir2}" />

    <!-- 外部类库所在目录 -->

    <property name="external-lib" value="lib" />

    <property name="external-lib-ospath" value="${project.home}/${external-lib}" />

    <!-- 生成class目录-->

    <property name="outdir-classes" value="${outdir-bin}/classes" />

    <property name="outdir-classes-ospath" value="${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="${dex-path}" />

    <!-- 经过aapt生成的资源包文件-->

    <property name="resources-package" value="${outdir-bin}/resources.ap_" />

    <property name="resources-package-ospath" value="${resources-package}" />

    <!-- 未认证apk-->

    <property name="out-unsigned-package" value="${outdir-bin}/${appName}-${version}-unsigned.apk" />

    <property name="out-unsigned-package-ospath" value="${out-unsigned-package}" />

    <!-- 证书文件? -->

    <property name="keystore-file" value="${keystore}" />

    <!-- 已认证apk-->

    <property name="out-signed-package" value="${outdir-bin}/${appName}-${version}.apk" />

    <property name="out-signed-package-ospath" value="${out-signed-package}" />

    <!-- 已优化apk-->

    <property name="zipalign-signed-package" value="${success_apk_out_dir}/${appName}_${create-time}.apk" />

    <!-- 输出路径的apk-->

    <property name="outdir-package" value="${project.outdir}/${appName}.apk" />

    <!-- 初始化工作 -->

    <target name="init" depends="copy-icon">

        <echo>Initializing all output directories...</echo>

        <delete dir="${outdir-bin}" />

        <delete dir="${outdir-gen}" />

        <mkdir dir="${outdir-gen}" />

        <mkdir dir="${outdir-bin}" />

        <mkdir dir="${outdir-classes}" />

    <!-- 把缺少的BuildConfig复制进去,暂时不知道如何生成?-->

        <copy file="Slidingmenu_BuildConfig.java" tofile="${outdir-gen}/com/jeremyfeinstein/slidingmenu/lib/BuildConfig.java">

             <filterset>

                <filter token="CONFIG.FROM" value="${package.from}"/>

             </filterset>

        </copy>

        <copy file="Facebook_BuildConfig.java" tofile="${outdir-gen}/com/facebook/android/BuildConfig.java">

             <filterset>

                <filter token="CONFIG.FROM" value="${package.from}"/>

             </filterset>

        </copy>

    </target>

    

    <target name="rename" depends="init">

    

  <replace file="${project.home}/AndroidManifest.xml" token="${oldpac}" value="${newpac}" encoding="UTF-8"/>

    <replace dir="${project.home}" includes="**/*.java" encoding="UTF-8">

    <replacefilter token="import ${oldpac}.R;" value="import ${newpac}.R;"/>

    </replace>

   

    <replace file="${project.home}/res/values/strings.xml" token="${oldpro}" value="${newpro}" encoding="UTF-8"/>

    </target>  

    <!-- 根据工程中的资源文件生成R.java文件-->

    <target name="GenRJAVA" depends="rename">

        <echo>Generating R.java / Manifest.java from the resources...</echo>

        <exec executable="${android-aapt}" failonerror="true">

            <arg value="package" /><!-- package表示打包-->

            <arg value="-m" /><!--m,J,gen表示创建包名的目录和R.javagen目录下-->

            <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-dir}/res" /><!-- 注意点:同时需要调用Libraryres-->

            <arg value="-S" />

            <arg value="${library-dir2}/res" /><!-- 注意点:同时需要调用Libraryres-->

            <arg value="-I" /><!-- I指定android包的位置-->

            <arg value="${android-jar}" />

            <arg value="--rename-manifest-package"/>

            <arg value="${package.manifest.name}"/>

            <arg value="--auto-add-overlay" /> <!-- 这个重要,覆盖资源,不然报错-->

        </exec>

        <!-- 根据库应用中的资源文件生成R.java文件-->

        <exec executable="${android-aapt}" failonerror="true">

            <arg value="package" />

            <arg value="-m" />

            <arg value="--auto-add-overlay" />

            <arg value="-J" />

            <arg value="${outdir-gen}" />

            <arg value="-M" />

            <arg value="${library-dir}/AndroidManifest.xml" /><!--库应用的manifest-->

            <arg value="-S" />

            <arg value="${resource-dir}" />

            <arg value="-S" />

            <arg value="${library-dir}/res" />

            <arg value="-I" />

            <arg value="${android-jar}" />

        </exec>

        <!-- 根据库应用中的资源文件生成R.java文件-->

        <exec executable="${android-aapt}" failonerror="true">

            <arg value="package" />

            <arg value="-m" />

            <arg value="--auto-add-overlay" />

            <arg value="-J" />

            <arg value="${outdir-gen}" />

            <arg value="-M" />

            <arg value="${library-dir2}/AndroidManifest.xml" /><!--库应用的manifest-->

            <arg value="-S" />

            <arg value="${resource-dir}" />

            <arg value="-S" />

            <arg value="${library-dir2}/res" />

            <arg value="-I" />

            <arg value="${android-jar}" />

        </exec>

    </target>

    <!-- 将工程及库应用中的java源文件编译成class文件-->

    <target name="compile" depends="GenRJAVA">

        <echo>Compiling java source code...</echo>

        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}" includeAntRuntime="false">

            <src path="${library-dir}/src"  /><!-- 库应用源码 -->

            <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下-->

            <classpath>

                <fileset dir="${library-dir}/libs" includes="*.jar" /><!--第三方jar包需要引用,用于辅助编译-->

            </classpath>

        </javac>

        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}" includeAntRuntime="false">

            <src path="${library-dir2}/src" /><!-- 库应用源码 -->

            <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下-->

            <classpath>

                <fileset dir="${library-dir2}/libs" includes="*.jar" /><!--第三方jar包需要引用,用于辅助编译-->

            </classpath>

        </javac>

        <javac encoding="UTF-8" destdir="${outdir-classes}" bootclasspath="${android-jar}" includeAntRuntime="false">

            <src path="${project.home}/src" /><!-- 工程源码-->

            <src path="${outdir-gen}" /><!-- 生成的class文件全部保存到bin/classes目录下-->

            <classpath>

                <fileset dir="${library}" includes="*.jar" /><!--第三方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="${android-dx}" failonerror="true">

            <arg value="--dex" />

            <arg value="--output=${dex-ospath}" /><!--输出-->

            <arg path="${outdir-classes}" /><!-- classes文件位置-->

            <arg value="${library}" /> <!-- libs下所有jar打包-->

        </exec>

    </target>

    <!-- 将资源文件放进输出目录 -->

    <target name="package-res-and-assets" depends="dex">

        <echo>打包资源文件。。。</echo>

        <exec executable="${android-aapt}" failonerror="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" /><!-- asset目录也打包-->

            <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>

        <!-- 打包成未签证的apk -->  

        <target name="package" depends="dex,package-res-and-assets">  

            <echo>打包成未签证的apk....</echo>  

            <java classpath="${sdklib}" 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>  

    <!-- apk进行签证-->

    <target name="jarsigner" depends="package">

        <echo>Packaging signed apk for release...</echo>

        <exec executable="${android-jarsigner}" failonerror="true">

            <arg value="-keystore" />

            <arg value="${keystore-file}" />

            <arg value="-storepass" />

            <arg value="111111" /><!-- 验证密钥完整性的口令,创建时建立的 -->

            <arg value="-keypass" />

            <arg value="222222" /> <!-- 专用密钥的口令,就是key密码-->

            <arg value="-signedjar" />

            <arg value="${out-signed-package-ospath}" /><!--输出-->

            <arg value="${out-unsigned-package-ospath}" /><!--未签名的apk -->

            <!-- 不要忘了证书的别名-->

            <arg value="lixianbao" />

        </exec>

    </target>

    <!-- 优化 -->

    <target name="optimize-app" depends="jarsigner">

      <echo> optimizing the application...</echo>

      <exec executable="${android-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>

3.命令行调用

我实现的是打包一个apk就要修改包名和项目名,所以必须知道当前项目中的包名和项目名

查看的方法:

a.查看配置文件AndroidManifest中的包名和定义的项目名

b.如果打包过apk后,使用命令行解析apk

aapt d badging   apk的路径

 

 

接下来就是更换包名、项目名、打包的命令,首先进入项目目录中,运行命令

ant -f build.xml -Doldpac=旧的包名 -Dnewpac=新的包名 -Doldpro=旧的项目名-Dnewpro=新的项目名

生成的apk就会到指定的目录中。

 

遇到的问题:1.资源图片的格式问题  图片的格式被修改了后缀名,本来是.jpg  被修改里后缀名.png  编译报错,需要使用图片格式转换器转换图片格式,替换原来的图片。