1. Flex SDK Ant
Flex開發者會遇到很多,比如自動構建,在一個有着N多模塊,N處源碼,構建過程復雜的Flex項目開發中,依賴人力手工構建項目非常不現實(機械重復且枯燥無味的過程,相信哪位開發人員都會避之唯恐不及,而且對於人力是非常大的浪費),而通過使用Ant,我們可以將這些工作交給機器來做,機器最適合干的就是這些程序固定,順次執行的工作,而且不辭辛苦,又快又好。
1.1. Ant簡介
Ant是一種基於Java的build工具。理論上來說,它有些類似於(Unix)C中的make,但沒有make的缺陷。目前的最新版本為:Ant 1.8.3。
既然我們已經有了make、gnumake、nmake、jam以及其他的build工具為什么還要要一種新的build工具呢?因為Ant的原作者在多種(硬件)平台上開發軟件時,無法忍受這些工具的限制和不便。類似於make的工具本質上是基於shell(語言)的:他們計算依賴關系,然后執行命令(這些命令與你在命令行敲的命令沒太大區別)。這就意味着你可以很容易地通過使用OS特有的或編寫新的(命令)程序擴展該工具;然而,這也意味着你將自己限制在了特定的OS,或特定的OS類型上,如Unix。
Ant就不同了。與基於shell命令的擴展模式不同,Ant用Java的類來擴展。(用戶)不必編寫shell命令,配置文件是基於XML的,通過調用target樹,就可執行各種task。每個task由實現了一個特定Task接口的對象來運行。
簡言之:當一個代碼項目大了以后,每次重新編譯,打包,測試等都會變得非常復雜而且重復,因此c語言中有make腳本來幫助這些工作的批量完成。在Java中應用是平台無關性的,當然不會用平台相關的make腳本來完成這些批處理任務了,ANT本身就是這樣一個流程腳本引擎,用於自動化調用程序完成項目的編譯,打包,測試等。除了基於JAVA是平台無關的外,腳本的格式是基於XML的,比make腳本來說還要好維護一些。
1.2. Flex支持Ant
打開SDK目錄,讓我們看看SDK中都包含了哪些內容:
ant包含Flex對Ant的支持庫,JAR和Java源碼都有,方便我們基於Ant完成對項目的構建
asdoc基於ASDOC我們可以很方便的生成代碼說明文檔,這個目錄則包含了對ASDOC的模板支持(調用asdoc的時候,所依賴的HTML模板文件就存放在這個目錄),以及一個用於Ant構建的示意XML配置文件,仔細瀏覽這個目錄下的文件,就可以對ASDOC有更好的了解。
bin按照慣例,我們基本也能猜出這個目錄下是什么,沒錯,就是Flex SDK中包含的工具集(編譯工具,庫打包工具,文檔生成工具,以及優化工具等等,這些可都是Flex開發所必須的利器),這些工具的具體用法,我們會在后面的文章中介紹。建議您將這個路徑配置到系統用戶的PATH中,方便通過命令行調用相應的工具。
frameworks這個也是重中之重,包含了Flex框架的核心源碼(您應該也已經了解到,Flex是基於AS3的一個框架,其底層代碼均是由AS3編寫的(注:不包含工具集,工具是Java編寫)),當您在Flex編程中有疑惑,看一眼源碼或許會讓您茅塞頓開。
include包含了一個用於編寫ActionScript擴展的C++頭文件:FlashRuntimeExtensions.h,如果您基於AIR做一些嵌入式應用(比如一個電視機),需要實現換台等功能,那就要用C++實現一些ActionScript的擴展。
install包含了用於移動開發的Android USB驅動程序
lib開發和編譯Flex應用所依賴的類庫,打開這個目錄您就能發現很多的JAR文件,比如mxmlc.jar,另外您可能已經注意到還有mxmlc_zh_CN.jar,顯然這些庫大都實現了本地化,方便我們的開發和調試。
runtimes包含運行時支持,但沒有Flash Player,只有AIR,包括AIR for Android的APK文件
samples一些實例文件,包括用於AIR在線無縫安裝的badge,和一些Flex主題。
templates包含一些模板文件,比如用於AIR應用描述的XML約束定義文檔,swfobject的示例代碼等等
着重了解一下Flex對Ant的支持情況。打開Flex SDK下的Ant目錄,會看到下面的文件結構:
lib中包含了Flex對Ant的任務支持庫:flexTasks.jar,src目錄中包含了flexTasks的Java源碼,build.xml則是用於構建flexTasks本身的配置文件(如果您修改了flexTask的Java源碼,可以用這個配置文件,重新編譯,並打包到flexTasks.jar)。
2. 環境搭建
需要安裝JDK、Ant,並設置環境變量;將flexTasks.jar這個文件放到您的Ant安裝目錄中的lib目錄中,並設置環境變量。
將該壓縮包解壓到一個目錄,然后配置環境變量:
set ANT_HOME=E:\AutoBuild\common\apache-ant-1.8.3
set path=%path%;%ANT_HOME%\bin;
set JAVA_HOME=C:\Program Files\Java\jdk1.6.0_26
set path=%path%;%JAVA_HOME%\bin
set path=%path%; F:\flex_sdk_4.1.0.16076\bin
運行下面命令成功,表示環境已經搭建好了:
3. 自動構建
使用ant自動構建一個項目時,首先應該編寫Ant構建文件。構建文件定義了構建過程,並被團隊開發中每個人使用。Ant構建文件默認命名為build.xml,也可以取其他的名字。只不過在運行的時候把這個命名當作參數傳給Ant。
3.1. build.properties文件
創建build.properties,即Ant的變量配置文件,該文件定義了需要用的配置參數。
3.2. build.xml文件
Ant構建文件是XML文件。每個構建文件定義一個唯一的項目(Project元素)。每個項目下可以定義很多目標(target元素),這些目標之間可以有依賴關系。當執行這類目標時,需要執行他們所依賴的目標。每個目標中可以定義多個任務,目標中還定義了所要執行的任務序列。Ant在構建目標時必須調用所定義的任務。任務定義了Ant實際執行的命令。Ant中的任務可以為3類。
可選任務。可選任務實來自第三方的任務,因此需要一個附加的JAR文件。
<project>標簽
每個構建文件對應一個項目。<project>標簽時構建文件的根標簽。它可以有多個內在屬性,就如代碼中所示,其各個屬性的含義分別如下。
(1) default表示默認的運行目標,這個屬性是必須的。
(2) basedir表示項目的基准目錄。
(3) name表示項目名。
(4) description表示項目的描述。
每個構建文件都對應於一個項目,但是大型項目經常包含大量的子項目,每一個子項目都可以有自己的構建文件。
<target>標簽
一個項目標簽下可以有一個或多個target標簽。一個target標簽可以依賴其他的target標簽。例如,有一個target用於編譯程序,另一個target用於聲稱可執行文件。在生成可執行文件之前必須先編譯該文件,因策可執行文件的target依賴於編譯程序的target。Target的所有屬性如下。
(1) name表示標明,這個屬性是必須的。
(2) depends表示依賴的目標。
(3) if表示僅當屬性設置時才執行。
(4) unless表示當屬性沒有設置時才執行。
(5) description表示項目的描述。
Ant的depends屬性指定了target的執行順序。Ant會依照depends屬性中target出現順序依次執行每個target。在執行之前,首先需要執行它所依賴的target。程序中的名為run的target的depends屬性compile,而名為compile的target的depends屬性是prepare,所以這幾個target執行的順序是prepare->compile->run。一個target只能被執行一次,即使有多個target依賴於它。如果沒有if或unless屬性,target總會被執行。
<mkdir>標簽
該標簽用於創建一個目錄,它有一個屬性dir用來指定所創建的目錄名,其代碼如下:<mkdir dir=”${class.root}”/>通過以上代碼就創建了一個目錄,這個目錄已經被前面的property標簽所指定。
<delete>標簽
該標簽用於刪除一個文件或一組文件,去屬性如下:
(1).file表示要刪除的文件。
(2).dir表示要刪除的目錄。
(3).includeEmptyDirs 表示指定是否要刪除空目錄,默認值是刪除。
(4).failonerror 表示指定當碰到錯誤是否停止,默認值是自動停止。
(5).verbose表示指定是否列出所刪除的文件,默認值為不列出。
<copy>標簽
該標簽用於文件或文件集的拷貝,其屬性如下。
(1).file 表示源文件。
(2).tofile 表示目標文件。
(3).todir 表示目標目錄。
(4).overwrite 表示指定是否覆蓋目標文件,默認值是不覆蓋。
(5).includeEmptyDirs 表示制定是否拷貝空目錄,默認值為拷貝。
(6).failonerror 表示指定如目標沒有發現是否自動停止,默認值是停止。
(7).verbose 表示制定是否顯示詳細信息,默認值不顯示。
3.3. 實例
這是使用flex ant自動構建項目的一個例子。下面通過這個例子來介紹如何編寫字段構建文件build.xml、build.properties。Ant自動化腳本完成了以下工作:
build.properties文件中定義了以下配置屬性
######################################
## project properties
######################################
# 定位到您的項目源碼的位置
# {$basedir} 是Ant默認支持的變量
SOURCE_DIR =${basedir}/src
# 設定SWF的輸出位置
OUTPUT_DIR = ${basedir}/bin
######################################
## tools
######################################
# flex sdk安裝目錄
FLEX_HOME=F:/flex_sdk_4.1.0.16076
# 定位到您的Lib路徑,如果存在的話
LIBS_DIR =${basedir}/lib
SDK_VERSION = 4.1.0.16076
LOCALE = en_US
build.xml構建文件
<?xml version="1.0"?>
<project name="flex ant autobuild" default="build" basedir="../">
<!—包含屬性定義文件tbuild.properties-->
<property file="./autobuild/build.properties" />
<!--定義任務的庫引用路徑,比如下面我們用到了mxmlc,必須讓Ant知道去哪里尋找這個任務的定義,包括類名稱和classpath。這里我們配置了4個,實際上用到了3個,即調用mxmlc完成編譯,調用html-wrapper對SWF進行HTML包裹,調用asdoc生成代碼文檔。compc是用來編譯庫(SWC)文件,這里我們沒有用到 -->
<taskdef name="mxmlc" classname="flex.ant.MxmlcTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<taskdef name="compc" classname="flex.ant.CompcTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<taskdef name="html-wrapper" classname="flex.ant.HtmlWrapperTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<taskdef name="asdoc" classname="flex.ant.AsDocTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
<!--完成當前構建任務所需的4個調用,首先是清理,如果bin下面有文件,刪除掉;然后是編譯,HTML包裹,和ASDoc文檔生成。-->
<target name="build">
<antcall target="clean"/>
<antcall target="compile"/>
<antcall target="wrapper"/>
<antcall target="asdoc"/>
</target>
<!--執行清理-->
<target name="clean">
<delete includeemptydirs="true">
<fileset dir="${OUTPUT_DIR}" includes="**/*"/>
</delete>
</target>
<!--執行編譯,注意debug參數,默認是false,如果您需要開啟Debug功能,可以將它設置為true(會增大文件體積)-->
<target name="compile">
<mxmlc
file="${SOURCE_DIR}/Main.as"
output="${OUTPUT_DIR}/Main.swf"
locale="${LOCALE}"
static-rsls="true"
accessible="true"
debug="false"
>
<!--加載Flex配置文件,如果您有特殊需求(比如要保留自定義的Metadata標簽,則可以設置自己定義的Flex配置文件)-->
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<!—設置源代碼位置-->
<source-path path-element="${SOURCE_DIR}"/>
<!--下面是對運行時共享庫RSL的配置,不是必須,如果您不采用RSL機制,可以刪除下面的定義;如果您沒用到一些RSL,可以刪除-->
<!--<runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/framework.swc">
<url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/framework_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
<url rsl-url="framework_${SDK_VERSION}.swz" policy-file-url=""/>
</runtime-shared-library-path>-->
<!--因為Flash Player內置的庫,不需要打包到SWF,所以對playerglobal采取了排除方式-->
<!--<external-library-path file="${FLEX_HOME}/frameworks/libs/player/10.1/playerglobal.swc" append="true"/>
<library-path file="${FLEX_HOME}/frameworks/libs/flash-integration.swc" append="true"/>
<library-path file="${FLEX_HOME}/frameworks/libs/authoringsupport.swc" append="true"/>-->
<!--引用本地化的庫支持-->
<library-path dir="${FLEX_HOME}/frameworks/locale/${LOCALE}" includes="*" append="true"/>
<!--當前項目的庫引用位置-->
<library-path dir="${LIBS_DIR}" includes="*" append="true"/>
</mxmlc>
<!--如果基於RSL,為了保證用戶在第一次使用RSL的時候,且鏈接不到Adobe服務器的情況下,保證應用可以正常運行,需要將這些Adobe簽名的RSL移動到項目的部署目錄下面。具體說明請參閱RSL的相關文章。-->
<!--<copy file="${FLEX_HOME}/frameworks/rsls/spark_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/spark_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/charts_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/charts_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/sparkskins_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/sparkskins_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/framework_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/framework_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/mx_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/mx_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/textLayout_2.0.0.232.swz" tofile="${OUTPUT_DIR}/textLayout_2.0.0.232.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/spark_dmv_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/spark_dmv_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/advancedgrids_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/advancedgrids_${SDK_VERSION}.swz"/>
<copy file="${FLEX_HOME}/frameworks/rsls/rpc_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/rpc_${SDK_VERSION}.swz"/>-->
</target>
<!--執行對SWF進行HTML包裹,可以傳遞一些參數-->
<target name="wrapper">
<html-wrapper
output="${OUTPUT_DIR}"
file="Main.html"
swf="Main"
history="true"
express-install="true"
version-detection="true"
version-major="10"
version-minor="2"
version-revision="0"
height="100%"
width="100%"
title="Main"
bgcolor="white"
/>
</target>
<!--執行ASDoc文檔生成-->
<target name="asdoc">
<asdoc output="${OUTPUT_DIR}/asdoc" lenient="true" failonerror="false">
<doc-sources path-element="${SOURCE_DIR}"/>
<load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
<library-path dir="${LIBS_DIR}" includes="*" append="true"/>
</asdoc>
</target>
</project>
運行ant會自動生成swf文件和相應的ASDoc文檔:
引用文章
[1]. http://www.riameeting.com/node/1009