使用Ant打包Apk

本文介绍了如何使用Ant打包Android应用Apk,包括Ant的下载与环境变量配置、打包项目的设置、Ant打包流程以及完整的build.xml脚本示例。通过Ant,开发者可以自动化构建和打包Android项目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当我们在Eclipse中对项目Run As Android Application的时候,会在bin文件夹下生成apk及其他一些文件,至于为什么生成这些文件开始我也不明白,查了相关资料才知道原来Android项目在Eclipse中是通过Ant进行构建的。学习Ant踩了很多坑,总结下来以后方便查看,也希望帮助更多的人。欢迎评论交流哦!

1、下载Ant并配置环境变量

Ant下载地址:http://ant.apache.org/bindownload.cgi;下载后直接解压到某目录下就OK。
添加Ant环境变量:ANT_HOME,变量值指向ant目录。
这里写图片描述

添加配置到Path中:%ANT_HOME%/bin;%ANT_HOME%/lib;
这里写图片描述

通过cmd命令行查看是否配置成功:
这里写图片描述

通过Ant打包Apk还需要配置JDK、Android SDK:

  • JDK的配置大家肯定都会了。
  • 添加系统环境变量ANDROID_HOME,值是Android sdk的路径。

2、配置打包项目

通过cmd进入到待代打包项目目录下执行android update project -n epeiwang -p . 命令。执行该命令后刷新项目,此时项目中会多build.xml
和local.properties文件。在项目下新建名为ant.properties的文件(非必须)然后将签名文件keystore放到项目下面或其他路径下。

  • build.xml :定义了基础构建方法和打包策略的脚本。
  • local.properties:存放sdk路径和其他一些本地配置。
  • ant.properties:定义一些变量,一般为签名文件的地址,密码、别名等。
  • 签名文件:用于对Ant打包后的Apk进行签名。

local.properties

sdk.dir=D:\\adt-bundle-windows\\sdk

ant.properties

#签名文件的路径
keystore=magic.keystore
#存储库口令
storepass=123456
#密匙库口令
keypass=123456
#别名
alias=magic

3、Ant打包流程

Ant打包主要流程:

1. 删除gen、bin目录并新建
2. 生成R.java类文件
3. 编译aidl文件
4. 编译源文件生成对应的class文件
5. 将.class文件转化成.dex文件
6. 打包资源文件
7. 生成未签名的apk包
8. 对未签名的apk包进行签名
9. 对签名的apk包进行字节对齐

这里写图片描述
(原图地址:http://blog.youkuaiyun.com/jason0539/article/details/44917745)

以上流程主要借助于sdk和jdk提供的相关工具进行完成。例如:aapt、dx、apkbuilder、jarsigner等,build.xml的编写其实就是对这些工具的使用。其中生成未签名的apk包可以,通过sdklib.jar配置新的apkbuilder使用或者直接使用sdklib.jar。

通过sdklib.jar配置新的apkbuilder.bat生成未签名的apk:
因为apkbuilder.bat在新版本的Android sdk中已经被移除,所以我们需要手动创建apkbuilder.bat文件,然后将此文件放在sdk tools目录下,apkbuilder.bat文件内容如下:

@echo off
rem Copyright (C) 2007 The Android Open Source Project
rem
rem Licensed under the Apache License, Version 2.0 (the "License");
rem you may not use this file except in compliance with the License.
rem You may obtain a copy of the License at
rem
rem      http://www.apache.org/licenses/LICENSE-2.0
rem
rem Unless required by applicable law or agreed to in writing, software
rem distributed under the License is distributed on an "AS IS" BASIS,
rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rem See the License for the specific language governing permissions and
rem limitations under the License.

rem don't modify the caller's environment
setlocal

rem Set up prog to be the path of this script, including following symlinks,
rem and set up progdir to be the fully-qualified pathname of its directory.
set prog=%~f0

rem Change current directory and drive to where the script is, to avoid
rem issues with directories containing whitespaces.
cd /d %~dp0

rem Check we have a valid Java.exe in the path.
set java_exe=
call lib\find_java.bat
if not defined java_exe goto :EOF

set jarfile=sdklib.jar
set frameworkdir=

if exist %frameworkdir%%jarfile% goto JarFileOk
    set frameworkdir=lib\

if exist %frameworkdir%%jarfile% goto JarFileOk
    set frameworkdir=..\framework\

:JarFileOk

set jarpath=%frameworkdir%%jarfile%

call "%java_exe%" -classpath %jarpath% com.android.sdklib.build.ApkBuilderMain %*

build.xml脚本中使用

    <!-- 根据classes.dex文件和resources.ap_生成未签名的apk包 -->
    <target
        name="package"
        depends="package-res-and-assets" >

        <echo message="package..."/>
        <exec
            executable="${apkbuilder}"
            failonerror="true" >

            <arg value="${unsigned-package}" /><!-- 输出 -->

            <arg value="-u" /><!-- u指创建未签名的包-->

            <arg value="-z" /><!-- 资源压缩包 -->

            <arg value="${resources-package}" />

            <arg value="-f" /><!-- dex文件 -->

            <arg value="${bin}/classes.dex" />

            <arg value="-rf" />

            <arg value="${src}" />

            <arg value="-rj" />

            <arg value="${libs}" />

            <arg value="-nf" />

            <arg value="${libs}" />
        </exec>
    </target>

直接使用sdklib.jar生成未签名的apk:
build.xml脚本中使用

    <!-- 根据classes.dex文件和resources.ap_生成未签名的apk包 -->
    <target
        name="package" depends="build-res-and-assets"
        >
        <echo message="package..."/>
          <java
            classname="com.android.sdklib.build.ApkBuilderMain"
            classpath="${sdklib}" >

            <arg value="${unsigned-package}" /> 

            <arg value="-u" /> <!-- 创建一个未签名的包 -->

            <arg value="-z" />  <!-- 资源压缩包 -->

            <arg value="${resources-package}" />

            <arg value="-f" /> <!-- dex文件-->

            <arg value="${bin}/classes.dex" />
        </java>

    </target>

4、完整的build.xml脚本

使用的时候直接复制该脚本并修改相关路径就可以,并不需要对每个工具的命令详细掌握。
通过cmd进入到待代打包项目目录下执行 ant make 命令即可进行打包。

<?xml version="1.0" encoding="UTF-8"?>
<project
    name="Test_HotFix"
    default="make" >

    <property file="local.properties" />

    <property file="ant.properties" />

    <property environment="env" />

    <condition
        property="sdk.dir"
        value="${env.ANDROID_HOME}" >

        <isset property="env.ANDROID_HOME" />
    </condition>

    <!-- 相关目录 -->
    <!-- 代表相对路径 -->
    <property
        name="basedir"
        value="." />

    <property
        name="sdk-tools"
        value="${sdk.dir}/tools" />

    <property
        name="sdk-build-tools"
        value="${sdk.dir}/build-tools/android-4.4.2" />

    <property
        name="android-jar"
        value="${sdk.dir}/platforms/android-19/android.jar" />

    <property
        name="framework-aidl"
        value="${sdk.dir}/platforms/android-19/framework.aidl" />
    <!-- 编译工具 -->

    <property
        name="aapt"
        value="${sdk-build-tools}/aapt.exe" />

    <property
        name="aidl"
        value="${sdk-build-tools}/aidl.exe" />

    <property
        name="dx"
        value="${sdk-build-tools}/dx.bat" />

    <property
        name="apkbuilder"
        value="${sdk-tools}/apkbuilder.bat" />

    <property
        name="jarsigner"
        value="${env.JAVA_HOME}/bin/jarsigner.exe" />

    <property
        name="zipalign"
        value="${sdk-build-tools}/zipalign.exe" />

    <!-- 输入目录 -->

    <property
        name="assets"
        value="${basedir}/assets" />

    <property
        name="res"
        value="${basedir}/res" />

    <property
        name="src"
        value="${basedir}/src" />

    <property
        name="libs"
        value="${basedir}/libs" />

    <!-- 输出目录 -->

    <property
        name="bin"
        value="${basedir}/bin" />

    <property
        name="gen"
        value="${basedir}/gen" />

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

    <property
        name="unsigned-package"
        value="${bin}/${ant.project.name}-unsigned.apk" />

    <property
        name="signed-package"
        value="${bin}/${ant.project.name}-singed.apk" />

    <property
        name="zipalign-package"
        value="${bin}/${ant.project.name}-zipalign.apk" />

    <!-- 初始化 -->
    <!-- 删除gen、bin目录并新建 -->
    <target name="init" >

        <echo message="init..." />

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

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

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

        <mkdir dir="${gen}" />
    </target>

    <!-- 生成R.java类文件 -->
    <target
        name="gen-R"
        depends="init" >

        <echo message="gen-R..." />

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

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

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

            <arg value="-J" />

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

            <arg value="-M" /><!-- M指定AndroidManifest.xml文件-->

            <arg value="AndroidManifest.xml" />

            <arg value="-S" /> <!-- S指定res目录 -->

            <arg value="${res}" />

            <arg value="-A" />

            <arg value="${assets}" />

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

            <arg value="${android-jar}" />
        </exec>
    </target>
    
    
    <!-- 编译aidl文件 -->
    <target
        name="aidl"
        depends="gen-R" >

        <echo message="aidl..."/>

        <apply
            executable="${aidl}"
            failonerror="true" >

            <arg value="-p${framework-aidl}" />

            <arg value="-I${src}" />

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

            <fileset dir="${src}" >
                <include name="**/*.aidl" />
            </fileset>
        </apply>
    </target>
    
    
    
    <!-- 编译源文件生成对应的class文件 -->
    <target
        name="compile"
        depends="aidl" >

        <echo message="compile..."/>
        <javac
            bootclasspath="${android-jar}"
            destdir="${bin}"
            encoding="gbk"
            includeantruntime="false"
            source="1.6"
            target="1.6" >

            <compilerarg value="-nowarn" />

            <src path="${src}" />

            <src path="${gen}" />

            <classpath>

                <fileset
                    dir="${libs}"
                    includes="*.jar" />
            </classpath>
        </javac>
    </target>
    
    
    <!--.class文件转化成.dex文件 -->
    <target
        name="dex"
        depends="compile" >
        <echo message="dex..."/>
        <exec
            executable="${dx}"
            failonerror="true" >

            <arg value="--dex" />

            <arg value="--output=${bin}" /><!-- 输出位置 -->

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

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

    <!-- 打包资源文件(包括res、assets、AndroidManifest.xml) -->
    <target
        name="package-res-and-assets"
        depends="dex" >

        <echo message="package-res-and-assets..."/>
        <exec
            executable="${aapt}"
            failonerror="true" >

            <arg value="package" />

            <arg value="-f" /><!-- 资源覆盖重写 -->

            <arg value="-M" />

            <arg value="AndroidManifest.xml" />

            <arg value="-S" />

            <arg value="${res}" />

            <arg value="-A" /><!-- 与R.java不同,需要asset目录也打包 -->

            <arg value="${assets}" />

            <arg value="-I" />

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

            <arg value="-F" /><!-- 输出资源压缩包 -->

            <arg value="${resources-package}" />
        </exec>
    </target>
    
    
    <!-- 根据classes.dex文件和resources.ap_生成未签名的apk包 -->
    <target
        name="package"
        depends="package-res-and-assets" >

        <echo message="package..."/>
        <exec
            executable="${apkbuilder}"
            failonerror="true" >

            <arg value="${unsigned-package}" /><!-- 输出 -->

            <arg value="-u" /><!-- u指创建未签名的包-->

            <arg value="-z" /><!-- 资源压缩包 -->

            <arg value="${resources-package}" />

            <arg value="-f" /><!-- dex文件 -->

            <arg value="${bin}/classes.dex" />

            <arg value="-rf" />

            <arg value="${src}" />

            <arg value="-rj" />

            <arg value="${libs}" />

            <arg value="-nf" />

            <arg value="${libs}" />
        </exec>
    </target>
    
    <!-- 对上面生成的apk包进行签名 -->
    <target
        name="jarsigner"
        depends="package" >

        <echo message="jarsigner..."/>
        <exec
            executable="${jarsigner}"
            failonerror="true" >

            <arg value="-verbose" />

            <arg value="-digestalg" />

            <arg value="SHA1" />

            <arg value="-sigalg" />

            <arg value="SHA1withRSA" />

            <arg value="-keystore" /><!-- keystore -->

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

            <arg value="-storepass" /><!-- 秘钥 -->

            <arg value="${storepass}" />

            <arg value="-keypass" /><!-- 秘钥口令-->

            <arg value="${keypass}" />

            <arg value="-signedjar" />

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

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

            <arg value="${alias}" /><!-- 别名 -->
        </exec>
    </target>

    <!-- 对签名的apk包进行字节对齐 -->
    <target
        name="make"
        depends="jarsigner" >

        <echo message="zipalign..."/>
        <exec
            executable="${zipalign}"
            failonerror="true" >

            <arg value="-f" />

            <arg value="-v" />

            <arg value="4" />

            <arg value="${signed-package}" />

            <arg value="${zipalign-package}" />
        </exec>

        <echo  message="make apk success!"  /> 
    </target>
    

</project>

参考文章:
http://blog.youkuaiyun.com/jason0539/article/details/44917745;
http://www.cnblogs.com/qianxudetianxia/archive/2012/07/04/2573687.html;

生命不止,奋斗不息!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值