文章 Android 使用Ant打渠道包讲解了如何使用Ant打渠道包,没有涉及具体的编译过程,例如使用Ant如何生成R文件等。那么今天,使用Ant来打一个Apk包!

  一、不管使用什么ide来打Apk包,一般会经过以下几个步骤:
1.生成R.java类文件
  使用Android SDK提供用aapt.exe生成R.Java文件。
2.将.aidl文件生成.java类文件
  使用Android SDK提供的aidl.exe生成相应Jva文件。
3.编译.java类文件生成class文件
  使用Jdk的javac命令编译Java源文件生成class文件。
4.将class文件打包生成classes.dex文件
  使用Android SDK提供的dx.bat将class文件转换成classes.dex文件。
5.打包资源文件(包括res、assets、androidmanifest.xml等)
  使用Android SDK提供的aapt.exe生成资源包文件resources.ap_。
6.生成未签名的apk安装文件
  使用Android SDK提供apkbuilder.bat打包资源和classes.dex文件,生成unsigned.apk。
7.对未签名的apk进行签名生成签名后的android文件
  用jarsinger命令对apk认证,生成signed.apk。

或者如下描述,

1.根据资源文件和AndroidManifest.xml生成R.java文件 
2.处理aidl,生成对应的java文件,如果没有aidl,则跳过 
3.编译工程源码(主项目,库)src目录下所有的源码,同时上边生成的R.java和aidl生成的java文件也会被编译生成相应的class文件 
4.将第3步生成的class文件打包生成.dex文件 
5.将资源文件打包,生成初始的apk 
6.将第4步生成的.dex文件加入到apk中生成未签名的包 
7.apk签名 

二、具体操作。

1.新建Android工程。

2.使用Android SDK命令创建Ant的build.xml。命令‘android update project –path .’ 。

3. 在IDE上刷新工程,可以看到项目根目录下多了build.xml以及local.properties两个文件。

这几步就不多说了,详情请参考这篇文章 Android 使用Ant打渠道包。主要还是看看custom_rules.xml这个文件,(custom_rules.xml这个文件需要手动创建),具体代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<project name="custom_rules" >
    
    <!-- 定义一个时间变量,打完包后跟渠道号一起命名apk -->
     <tstamp>
       <format property="pktime"  pattern="yyyyMMddHHmm"  locale="hour"/>
    </tstamp>
    
    <!-- 定义一个版本号变量,打完包后一起命名apk -->
    <property name="version"  value="${test.server.url}" />
    
    <property name="basedir" value=" " />  
    <property name="library-dir" value="${basedir}">  
    </property>  
    <!-- SDK目录(获取操作系统环境变量ANDROID_SDK_HOME的值) -->  
    <property name="sdk-folder" value="${sdk.dir}" />  
    <!-- SDK指定平台目录 -->  
    <property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-19" />  
    <!-- SDK中tools目录 -->  
    <property name="sdk-tools" value="${sdk-folder}/tools" />  
    <!-- SDK指定平台中tools目录 -->  
    <property name="sdk-platform-tools" value="${sdk-folder}/build-tools/23.0.1" />  
  
    <!-- 使用到的命令(当前系统为windows,如果系统为linux,可将.bat文件替换成相对应的命令) -->  
    <property name="aapt" value="${sdk-platform-tools}/aapt.exe" />  
    <property name="aidl" value="${sdk-platform-tools}/aidl.exe" />  
    <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" />  
  
    <!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar -->  
    <property name="android-jar" value="${sdk-platform-folder}/android.jar" />  
  
    <!-- 编译aidl文件所需的预处理框架文件framework.aidl -->  
    <property name="framework-aidl" value="${sdk-platform-folder}/framework.aidl" />  
  
    <!-- 生成R文件的相对目录 -->  
    <property name="outdir-gen" value="gen" />  
    <!-- 编译后的文件放置目录 -->  
    <property name="outdir-bin" value="out" />  
  
    <!-- 清单文件 -->  
    <property name="manifest-xml" value="AndroidManifest.xml" />  
    <!-- 源文件目录 -->  
    <property name="resource-dir" value="res" />  
    <property name="asset-dir" value="assets" />  
    <!-- java源文件目录 -->  
    <property name="srcdir" value="src" />  
    <property name="srcdir-ospath" value="${basedir}/${srcdir}" />  
    <!-- 外部类库所在目录 -->  
    <property name="external-lib" value="libs" />  
    <property name="external-lib-ospath" value="${basedir}/${external-lib}" />  
  
    <!-- 生成class目录 -->  
    <property name="outdir-classes" value="${outdir-bin}" />  
    <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}" />  
  
    <!-- 经过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-bin}/${app.name}-unsigned.apk" />  
    <property name="out-unsigned-package-ospath" value="${basedir}/${out-unsigned-package}" />  
  
    <!-- 证书文件 -->  
    <property name="keystore-file" value="${key.store}" />  
  
    <!-- 已认证apk包 -->  
    <property name="out-signed-package" value="${outdir-bin}/${app.name}_${pktime}${version}.apk" />  
    <property name="out-signed-package-ospath" value="${basedir}/${out-signed-package}" />  
    
     <target name="buildAll" >
        <antcall target="clean" />
        <antcall target="init" />
        <antcall target="gen-R" />
        <antcall target="aidl" />
        <antcall target="compile" />
        <antcall target="dex" />
        <antcall target="package-res-and-assets" />
        <antcall target="package" />
        <antcall target="jarsigner" />
        <antcall target="release" />
    </target>

   <!-- 初始化工作 -->  
    <target name="init">  
        <echo>Initializing all output directories...</echo>  
        <delete dir="${outdir-bin}" />  
        <delete dir="${outdir-gen}" />
        <mkdir dir="${outdir-bin}" />  
         <mkdir dir="${outdir-gen}" />
        <mkdir dir="${outdir-classes}" />  
    </target>  
  
    <!-- 根据工程中的资源文件生成R.java文件 -->  
    <target name="gen-R" depends="init">  
        <echo>Generating R.java from the resources...</echo>  
        <exec executable="${aapt}" failοnerrοr="true">  
  <!-- package表示打包-->
            <arg value="package" />  
  <!--m,J,gen表示创建包名的目录和R.java到gen目录下 -->  
            <arg value="-m" />  
            <arg value="--auto-add-overlay" />  
            <arg value="-J" />  
            <arg value="${outdir-gen}" />  
  <!-- M指定AndroidManifest.xml文件-->  
            <arg value="-M" />  
            <arg value="${manifest-xml}" />  
  <!-- S指定res目录,生成对应的ID,可多个--> 
            <arg value="-S" />  
  <!--  注意点:同时需要调用Library的res-->  
            <arg value="${resource-dir}" />  
            <arg value="-S" />  
            <arg value="${library-dir}/${resource-dir}" />  
            <arg value="--extra-packages" />  
            <arg value="com.mobcent.share.android" />  
            <arg value="-A" />  
            <arg value="${asset-dir}" />  
  <!-- I指定android包的位置-->  
            <arg value="-I" />  
            <arg value="${android-jar}" />  
  <arg value="--auto-add-overlay" /> <!-- 这个重要,覆盖资源,不然报错-->  
        </exec>  
    </target>  
  
  
    <!-- 编译aidl文件 -->  
    <target name="aidl" depends="gen-R">  
        <echo>Compiling .aidl into java files...</echo>  
        <apply executable="${aidl}" failοnerrοr="true">  
            <!-- 指定预处理文件 -->  
            <arg value="-p${framework-aidl}" />  
            <!-- aidl声明的目录 -->  
            <arg value="-I${srcdir}" />  
            <!-- 目标文件目录 -->  
            <arg value="-o${outdir-gen}" />  
            <!-- 指定哪些文件需要编译 -->  
            <fileset dir="${srcdir}">  
                <include name="**/*.aidl" />  
            </fileset>  
        </apply>  
    </target>  
  
    <!-- 将工程中的java源文件编译成class文件 -->  
    <target name="compile" depends="aidl">  
        <echo>Compiling java source code...</echo>  
        <javac encoding="utf-8" target="1.6" destdir="${outdir-classes}" bootclasspath="${android-jar}">  
            <src path="src" />  <!-- 工程src目录-->  
            <src path="gen" />  <!-- 工程gen目录 -->  
            <classpath>  
                <fileset dir="${external-lib-ospath}" includes="*.jar" />  
            </classpath>  
        </javac>  
    </target>  
  
    <!-- 将.class文件转化成.dex文件 -->  
    <target name="dex" depends="compile">  
        <echo>Converting compiled files and external libraries into a .dex  
            file...  
        </echo>  
            <exec  executable="${dx}" failοnerrοr="true" > 
            <arg value="--dex" />  
            <!-- 输出文件 -->  
            <arg value="--output=${dex-ospath}" />  
            <!-- 要生成.dex文件的源classes和libraries -->  
            <arg value="${outdir-classes-ospath}" />  <!-- classes文件位置 -->
            <arg value="${external-lib-ospath}" />  <!-- 把libs下所有jar打包 -->
       </exec>
    </target>  
  
  
    <!-- 将资源文件放进输出目录 -->  
    <!--在这截断-->  
    <target name="package-res-and-assets" depends="dex">  
        <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="-A" />  
            <arg value="${asset-dir}" />  
            <arg value="-S" />  
            <arg value="${library-dir}/${resource-dir}" />  
            <arg value="-A" />  <!-- asset目录也打包 --> 
            <arg value="${library-dir}/${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>Packaging unsigned apk for release...</echo>  
        <exec executable="${apkbuilder}" failοnerrοr="true">  
            <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-dir}/libs"/>  
        </exec>  
        <echo>It will need to be signed with jarsigner before being published.  
        </echo>  
    </target>  
  
  
    <!-- 对apk进行签证 -->  
    <target name="jarsigner" depends="package">  
        <echo>Packaging signed apk for release...</echo>  
        <exec executable="${jarsigner}" failοnerrοr="true">  
            <arg value="-keystore" />  
            <arg value="${keystore-file}" />  
            <arg value="-storepass" />  
            <arg value="${key.store.password}" />  
            <arg value="-keypass" />  
            <arg value="${key.alias.password}" />  
            <arg value="-signedjar" />  
            <arg value="${out-signed-package-ospath}" />  
            <arg value="${out-unsigned-package-ospath}" />  
            <!-- 不要忘了证书的别名 -->  
            <arg value="${key.alias}" />  
        </exec>  
    </target>  
  
    <!-- 发布 -->  
    <target name="release" depends="jarsigner">  
        <!-- 删除未签证apk -->  
        <delete file="${out-unsigned-package-ospath}" />  
        <echo>APK is released. path:${out-signed-package-ospath}</echo>  
    </target>  
  
</project>

代码都有注释,如有不清楚的标签,请查Ant看官网文档。

下面再看看ant.properties文件,具体如下,

#keystore
key.store=E:\\me.keystore
#keystore
key.store.password=111111
#alias 
key.alias=xinxing
#alias
key.alias.password=111111
apk.dir=./apk
app.name=ant_app
# 
version=(1.2.1)

keystore密码,apk名称,版本号等。

三、打包。

1.首先在命令行下,定位到项目所在的目录,

idea 编译器storm项目ant 编译打jar包_android

2. 在命令行中,输入打包命令,稍等片刻,如出现下面截图,则打包成功,

idea 编译器storm项目ant 编译打jar包_jar_02

2. 在项目的根目录下,有一个‘out’文件夹,

idea 编译器storm项目ant 编译打jar包_xml_03

 

idea 编译器storm项目ant 编译打jar包_ant_04

         打包前项目截图                                                                                            打包后截图

至此,使用Ant打包就完成了!

四、小结。

  使用Ant打包Apk的步骤就是上面说的7步,每一步都是生成不同的文件或者文件夹。相信,只要你多加练习,也会掌握的!