以前在做JavaEE项目的时候曾经听说过这个名字,但是由于没有用到,所以也没有去学习。最近在研究Android打包的时候,看了下build.xml文件,甚是迷糊,于是学习一下,稍有心得。
二、什么是ant?
ant是一种基于Java的打包工具,非常类似于Linux下的makefile。ant有自己的语法和规范,通常用xml来承载。ant可以集成代码生成、编译、打包等功能(需要说明一下,ant本身并不具备这些功能,只是调用者),使用ant能做到编译、打包一系列流程的自动化,就像生产流水线,一条指令,全程自动生产。
ant工具是使用Java语言编写的,所以依赖jdk,安装ant必须先安装好jdk。同样ant很多扩展的自定义的功能同样可以使用Java编写,后续会详细介绍。
三、ant的基本语法和规范
ant的构建脚本是使用xml文件承载的,缺省命名为build.xml。进入其文件所在目录,可以在cmd中直接使用ant命令调用(前提是先配好bin目录的环境变量)。
我们先来看一下build.xml文件的基本结构:
<?xml version="1.0" encoding="UTF-8"?> <project name="test" default="build"> <property name="file.dir" value="D://"/> <property file="local.properties" /> <loadproperties srcFile="project.properties" /> <import file="rules.xml" optional="true" /> <target name="build"> <echo>runing...</echo> </target> <target name="debug" depends="build"> <echo level="info">${file.dir} debugging...</echo> </target> </project>
project 根标签。name属性表示项目名称,没什么作用;default属性表示默认执行命令,cmd命令行中使用ant和ant default属性值(本例是ant build) 两种方式等效。
property 定义类标签。可以定义一些常量值,需要注意:定义后理论不能再修改(其实可以通过第三方库修改)。比如第3行定义了一个file.dir的变量,值为”D://“,引用时使用 ${file.dir}调用。第4行,是引入一个properties文件(里面定义了很多property),相当于导包。
loadproperties 引用标签。功能和第4行<property file=""/>等同,表示引入一个properties定义集群。好处是便于封装和管理。
import 引入标签。和loadproperties不同的是,import是引入另一个构建文件,包括变量和执行命令。
target 执行标签。可以在cmd命令行中直接ant + target执行,比如以上脚本可以执行: ant build 和 ant debug。target标签中有个depends属性,表示执行命令依赖。如果要执行debug命令,会自动先执行depends里面的命令。以上脚本执行 ant debug,实际是执行了 ant build 和 ant debug
echo 日志标签。表示日志输出,能在cmd命令中打印显示,level属性表示:日志级别。 比较特殊的是echo中可以引用变量,用法同变量调用方式${name}。
以上就是ant最基本的语法规范,我们执行下ant debug命令看看结果。
分析以上执行过程:cmd进入build.xml所在目录,执行target名为debug的命令,由于debug依赖于build,所以先执行build命令,打印出runing... 然后再执行debug命令下的语句,打印出D:// debugging... (注意其中引用了一个变量),执行完毕!
四、ant的常用语法
1、文件语句
文件操作是ant中最常用的基本操作,包括创建、复制、删除、遍历等。由于ant涉及最多的就是文件操作,所以它的api相对来说非常丰富,让我们来逐一介绍和学习。
创建:mkdir标签。 传入一个文件路径,直接创建出一个文件目录。然而不知为何ant没有提供创建文件的功能。
<mkdir dir="D:/test"/><span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);"> </span>
删除:delete标签。删除文件或文件夹。
<delete file="D:/test/example.txt"/> <delete dir="D:/test"/>移动:move标签。包括文件重命名、文件移动、文件目录移动。
<!-- 重命名 --> <move file="D:/test/example1.txt" tofile="D:/test/example2.txt"/> <!-- 移动文件至新目录,新目录会自动创建 --> <move file="D:/test/example2.txt" todir="D:/test2"/> <!-- 文件夹移动 --> <move dir="D:/test/example2.txt" todir="D:/test2"/>
<!-- 文件复制,指定新文件名 --> <copy file="D:/test/example.txt" tofile="D:/test/example2.txt"/> <!-- 文件复制,指定新文件目录 --> <copy file="D:/test/example.txt" todir="D:/test/new/"/> <!-- 文件夹复制,指定新文件夹 --> <copy dir="D:/test/" todir="D:/test/new/"/>
2、条件语句
condition标签,配合istrue或者isfalse使用。
<condition property="check"> <istrue value="false" /> </condition> <target name="build" if="check"> <echo>build running...</echo> </target>
<condition property="check"> <isfalse value="true" /> </condition> <target name="build" if="check"> <echo>build running...</echo> </target>需要注意下,istrue和isfalse两种标签不能同时存在。
除了直接使用istrue指定条件语句的值,还能动态地使用equals比较变量,比如:
<property name="id" value="99"></property> <condition property="check"> <equals arg1="${id}" arg2="100"/> </condition> <target name="build" if="check"> <echo>build running...</echo> </target>
<property name="ant-contrib" value="E:\\Android\\android-sdk\\tools\\lib\\ant-contrib-1.0b3.jar"></property> <taskdef name="foreach" classname="net.sf.antcontrib.logic.ForEach" classpath="${ant-contrib}"/> <target name="build"> <foreach list="1,2,3,4,5,6,7,8,9" param="number" delimiter="," target="log"/> </target> <target name="log"> <echo>foreach running: ${number}</echo> </target>以上语句稍微有些复杂,我们一句句来理。第一句property定义一个变量,即扩展jar包ant-contrib-1.0b3.jar所在的文件位置。第二句taskdef标签,表示定义自定义名为foreach的标签,需要引用类名和类路径,这是使用foreach的前提条件,必须先定义好。然后我们就可以在target任务中愉快地使用for循环了。
4、自定义语句
ant的魅力所在之处就是强大的自定义语句,比如上面的foreach语句。ant官方库只定义了一些简单的语句,但是在实际项目中远远不足以满足我们的需要,比如新建一个文件。这里我们就用自定义语句来实现下。
ant的原理是每个语句标签映射一个java类文件,每个标签里的属性则映射java类的变量,有点类似spring中xml映射javabean。每个ant标签映射的java类文件不是随意编写的,有一定的规范。
在ant安装目录下的lib文件目录中有个名为ant.jar的包,这个就是ant的规范标准库,自定义语句Java类都需要依赖它来编译,同时每个语句必须继承其中名为Task.java的基类,复写execute方法执行自定义操作。
package com.ant.test; import java.io.File; import java.io.IOException; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Task; public class FileCreater extends Task{ private String fileName; public void setName(String fileName){ this.fileName = fileName; } @Override public void execute() throws BuildException { try { new File(fileName).createNewFile(); } catch (IOException e) { log("create file '" + fileName + "' failed!"); } log("create file '" + fileName + "' successful!"); super.execute(); } }上面定义了创建文件的自定位标签,把这个java文件打成jar包,然后就可以在build.xml使用了,xml内容如下:
<property name="fileJar" value="D:/file.jar"></property> <taskdef name="filecreater" classname="com.ant.test.FileCreater" classpath="${fileJar}"/> <target name="build"> <filecreater name="D:/test.txt"/> </target>以上执行的操作是创建一个路径为D:/test.txt的文件。filecreater是映射FileCreater.java的自定义标签,name属性传入文件路径名,会自动 反射调用 FileCreater.java中的setName方法注入参数值。在FileCreater.java中有个log打印输出方法,可以在cmd中输出,极大方便我们的调试。执行结果如下:
------------------------------------------------------------------------------------------------>
好了,ant相关的就先写到这里,权当抛砖引玉^-^