Packaging Android apps with ant

1. Install and configure ant

Ant is a Java-based compilation and packaging tool. The download address is: http://ant.apache.org/bindownload.cgi

After downloading and decompressing, you need to configure environment variables for ant, as shown below:

 



 

Then, add ;%ANT_HOME%/bin;%ANT_HOME%/lib; to Path

After the configuration is complete, open the Dos window and enter the command ant. If the following is shown, the configuration is successful



 

2. Instructions for using ant to package Android applications

Using ANT to package an application generally goes through the following steps:

1. Use the aapt command to generate the R.java file

2. Use the aidl command to generate the corresponding java file from the aidl file of the project

3. Compile the java source file with the javac command to generate the class file

4. Convert the class file to classes.dex file with dx.bat

5. Use the aapt command to generate the resource package file resources.ap_

6. Use apkbuilder.bat to package resources and classes.dex files to generate unsigned.apk

7. Use the jarsinger command to authenticate the apk and generate signed.apk

In order to facilitate understanding and memory, a flow chart is used to illustrate the above processes:



 

In fact, this is the process of apk generation, and the use of ant packaging is implemented according to this process.

3. Create an example project

首先,我们创建一个测试Android工程,打开dos命令窗口,进入工程根目录,然后使用android update project --path . 命令,在工程根目录之下,就会生成一个build.xml文件,这个就是ant的编译打包的配置文件。



 

4、配置ant编译打包脚本

也就是根据实际的编译环境来编写build.xml文件,下面将详细解释编译脚本的内容:

4.1、定义相关变量属性

 

<?xml version="1.0" encoding="UTF-8"?>
<project name="MainActivity" default="release">
<property file="local.properties" />
<!-- 应用名称 -->  
    <property name="appName" value="${ant.project.name}"/>  
    <!-- SDK目录(获取操作系统环境变量ANDROID_SDK_HOME的值) -->  
    <property name="sdk-folder" value="${env.ANDROID_SDK_HOME}" />  
    <!-- SDK指定平台目录 -->  
    <property name="sdk-platform-folder" value="${sdk-folder}/platforms/android-22"/>  
    <!-- SDK中tools目录 -->  
    <property name="sdk-tools" value="${sdk-folder}/tools" />  
    <!-- SDK指定平台中tools目录 -->  
    <property name="sdk-platform-tools" value="${sdk-folder}/build-tools/22.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="Javacpath"  value="/usr/bin/javac" /> 
    <property name="jarsigner" value="${env.JAVA_HOME}/bin/jarsigner.exe" />  
      
    <!-- 编译需要的jar; 如果项目使用到地图服务则需要maps.jar -->  
    <property name="android-jar" value="${sdk-platform-folder}/android.jar" />  
<!--     <property name="android-maps-jar" value="${sdk-folder}/add-ons/addon_google_apis_google_inc_8/libs/maps.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="bin" />  
      
    <!-- 清单文件 -->  
    <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}/${appName}-unsigned.apk" />  
    <property name="out-unsigned-package-ospath" value="${basedir}/${out-unsigned-package}" />  
      
    <!-- 证书文件 -->  
    <property name="keystore-file" value="E:/keystore" />  
      
    <!-- 已认证apk包 -->  
    <property name="out-signed-package" value="${outdir-bin}/${appName}.apk" />  
<property name="out-signed-package-ospath" value="${basedir}/${out-signed-package}" />
 <!-- 混淆配置 -->
    <property name="proguard-home" value="${sdk-tools}/proguard/lib"/>
    <property name="proguard-file" value="proguard-project.txt" />
    <path id="lib_classpath">
		
        <fileset dir="${external-lib}">
         	<include name="*.jar" />
         </fileset> 
         <pathelement location="${android-jar}" />
	</path>

 4.2、编译前初始化

 

 

<!-- 初始化工作 -->  
    <target name="init">  
        <echo>Initializing all output directories...</echo>  
        <delete dir="${outdir-bin}" />  
        <mkdir dir="${outdir-bin}" />  
        <mkdir dir="${outdir-classes}" />  
    </target>

 这一步是先删除掉输出目录,再新创建输出目录,也就是清理文件的工作。

 

 

4.3、通过aapt工具将资源文件生成R.java

 

<!-- 根据工程中的资源文件生成R.java文件  -->  
    <target name="gen-R" depends="init">  
        <echo>Generating R.java from the resources...</echo>  
        <exec executable="${aapt}" failonerror="true">  
            <arg value="package" />  
            <arg value="-f" />  
            <arg value="-m" />  
            <arg value="-J" />  
            <arg value="${outdir-gen}" />  
            <arg value="-S" />  
            <arg value="${resource-dir}" />  
            <arg value="-M" />  
            <arg value="${manifest-xml}" />  
            <arg value="-I" />  
            <arg value="${android-jar}" />  
        </exec>  
    </target>  

 参数说明:

 

-f  强制覆盖已存在的文件。
-m  在-J指定的位置下自动生成相应的包的目录。
-J  指定R.java文件生成的目录。
-S  指定资源目录。
-M  指定清单文件。
-I  引入类库

 

 

4.4、编译aidl文件

 

<!-- 编译aidl文件 -->  
    <target name="aidl" depends="gen-R">  
        <echo>Compiling .aidl into java files...</echo>  
        <apply executable="${aidl}" failonerror="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>  

 4.5、通过Javac将Java源文件编译成class文件,如果编译需要第三方包,必须指定所需的依赖包,不然编译会报错。

 

 

<!-- 将工程中的java源文件编译成class文件 -->  
    <target name="compile" depends="aidl">  
        <echo>Compiling java source code...</echo>  
        <javac executable="${Javacpath}" encoding="utf-8" target="1.7"  destdir="${outdir-classes}"  includeantruntime="true">  
            <src path="${srcdir-ospath}"/>
	        <src path="${outdir-gen}"/>
	        <classpath refid="lib_classpath"/>
        </javac>  
         
    </target>  

 

 

注意:如果需要混淆代码,则加入下面步骤

 

<!-- 混淆代码 -->
    <target name="proguard" depends="compile" >
     <echo>Proguad classes....</echo>
        <jar basedir="${outdir-classes}" destfile="temp.jar" />
        <java  failonerror="true" fork="true"  jar="${proguard-home}/proguard.jar" >
            <jvmarg value="-Dmaximum.inlined.code.length=32" />
            <!-- jar包所在地址 -->
            <arg value="-injars temp.jar" />
            <!-- 输出地址 -->
            <arg value="-outjars optimized.jar" />
            <!-- 不预校验 -->
            <arg value="-dontpreverify" />
            <arg value="-dontoptimize" />
            <!-- 混淆时不会产生形形色色的类名 -->
            <arg value="-dontusemixedcaseclassnames" />
            <arg value="-repackageclasses &apos;&apos;" />
            <arg value="-allowaccessmodification" />
            <!-- 忽略警告 -->
            <arg value="-ignorewarning"/>
            <!-- 混淆配置的引用 -->           
            <arg value="@${proguard-file}"/>             
        </java>
        <delete file="temp.jar" />
        <delete dir="${outdir-classes}" />
        <mkdir dir="${outdir-classes}" /> 
        <unzip
            dest="${outdir-classes}" src="optimized.jar" />
        <delete file="optimized.jar" />
    </target>

4.6、将.class文件转化为.dex文件

 

<!-- 将.class文件转化成.dex文件 -->  
    <target name="dex" depends="compile">  
        <echo>Converting compiled files and external libraries into a .dex file...</echo>  
        <exec executable="${dx}" failonerror="true">  
            <arg value="--dex" />  
            <!-- 输出文件 -->  
            <arg value="--output=${dex-ospath}" />  
            <!-- 要生成.dex文件的源classes和libraries -->  
            <arg value="${outdir-classes-ospath}" />  
            <arg value="${external-lib-ospath}"/>  
        </exec>  
</target>

 4.7、通过aapt将资源文件打包至输出目录

 

<!-- 将资源文件放进输出目录 -->  
    <target name="package-res-and-assets">  
        <echo>Packaging resources and assets...</echo>  
        <exec executable="${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="-A" />  
            <arg value="${asset-dir}" />  
            <arg value="-I" />  
            <arg value="${android-jar}" />  
            <arg value="-F" />  
            <arg value="${resources-package}" />  
        </exec>  
    </target>

 参数说明:

-f 强制覆盖

-M 指定Manifest文件

-S 指定资源目录

-A 指定资产目录

-I 指定引入的类库

-F 指定要生成的包

 

 

4.8、通过apkbuilder工具打包成未签名的apk

<!-- 打包成未签证的apk -->  
    <target name="package" depends="dex, package-res-and-assets">  
        <echo>Packaging unsigned apk for release...</echo>  
        <exec executable="${apkbuilder}" failonerror="true">  
            <arg value="${out-unsigned-package-ospath}" />  
            <arg value="-u" />  
            <arg value="-z" />  
            <arg value="${resources-package-ospath}" />  
            <arg value="-f" />  
            <arg value="${dex-ospath}" />  
            <arg value="-rf" />  
            <arg value="${srcdir-ospath}" />  
        </exec>  
        <echo>It will need to be signed with jarsigner before being published.</echo>  
    </target>

 4.9、通过jarsigner工具对apk签名

<!-- 对apk进行签证 -->  
    <target name="jarsigner" depends="package">  
        <echo>Packaging signed apk for release...</echo>  
        <exec executable="${jarsigner}" failonerror="true">  
            <arg value="-keystore" />  
            <arg value="${keystore-file}" />  
            <arg value="-storepass" />  
            <arg value="123456" />  
            <arg value="-keypass" />  
            <arg value="123456" />  
            <arg value="-signedjar" />  
            <arg value="${out-signed-package-ospath}" />  
            <arg value="${out-unsigned-package-ospath}"/>  
            <!-- 不要忘了证书的别名 -->  
            <arg value="xxx"/>  
        </exec>  
    </target>

 主要是配置签名文件的路径和签名的相关信息

 

4.10发布apk

<!-- 发布 -->  
    <target name="release" depends="jarsigner">  
        <!-- 删除未签证apk -->  
        <delete file="${out-unsigned-package-ospath}"/>  
        <echo>APK is released. path:${out-signed-package-ospath}</echo>  
    </target>

 

5、执行ant编译打包



 

编译打包成功之后,在输出目录下,就会生成相应的apk文件。



 

6eclipse使用ant打包

6.1、ant插件配置

选择“window”—“Preferences”—“Ant”—“Runtime”—“Ant Home”,配置好ant的路径。



 

 

 

 

 

 

 

6.2、执行ant编译

右键工程目录下的build.xml文件,选择“Run as”—“Ant Build”



 

弹出的ant编译窗口中,会把bild.xml脚本里面编写的所有target操作列出来,勾选需要操作的步骤之后,执行“run”操作。



 

执行编译之后,在consloe控制台可以看到编译过程。



 

 

 

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326822554&siteId=291194637