瞭解Flex SDK系列教程(1.Ant和FlexTask)

轉:http://www.riameeting.com/node/1009

推薦兩篇教程
http://www.adobe.com/devnet/flex/articles/flex_ant_pt1.html
http://www.adobe.com/devnet/flex/articles/flex_ant_pt2.html
中文版本的只找到了Part1 http://www.adobe.com/cn/devnet/flex/articles/flex_ant_pt1.html

基於Ant,還是會有很多重複的構建過程,對於消除重複,Apache有更好的解決方案:Maven,Maven實際上是一個項目管理工具,而不簡單是構建工具。關於Maven,RIAMeeting之前有過一次在線課程(http://www.riameeting.com/node/971),還不太瞭解Maven的朋友,可以看一下。


聲明:本文爲RIAMeeting原創文章,您可以自由轉載,但請務必說明文章來源並保留原文鏈接,謝謝!

最近Flex/AS開發者的大事,莫過於Adobe發佈了Flash Builder 4.5 (包含Flex SDK 4.5,點擊這裏查看新聞報道) 和 Adobe CS5.5(下載地址請登錄Adobe官網,這裏是相關學習資料)。新版IDE的重點是針對移動應用開發的支持(Android,iOS等等),不過,這些不是文本要探討的內容。讓我們從Flex SDK着手,瞭解一些Flex的內在機制和對企業級開發的支持,這也有助於我們更好的理解Flex這門技術。

獲取Flex SDK

首先,從哪裏可以獲取Flex SDK?最簡單最直接的方式,就是安裝Flash Builder(以下簡稱FB),當您安裝完畢,可以打開FB的安裝位置,目錄sdks下面,就是目前比較常用的Flex SDK版本。具體位置因您的安裝選擇而異,比如筆者的路徑是:D:\Program Files (x86)\Adobe\Adobe Flash Builder 4.5\sdks。因爲筆者安裝的是FB 4.5,所以目錄中實際上包含了兩個版本的SDK:3.6和4.5,如圖所示:

如果您安裝的是FB4.0,則看到的最新SDK版本應該是4.0或4.1。而那個比較老的3.6版本,主要是爲了兼容之前的Flex3項目(如果您有比較老版本的項目,而且不打算做代碼變更,那麼3.6這個版本的SDK是必須的)。本文的探討將以最新的SDK,也就是4.5爲準。

打開SDK 4.5這個目錄,讓我們看看SDK中都包含了哪些內容:

  1. ant 包含Flex對Ant的支持庫,JAR和Java源碼都有,方便我們基於Ant完成對項目的構建
  2. asdoc 基於ASDOC我們可以很方便的生成代碼說明文檔,這個目錄則包含了對ASDOC的模板支持(調用asdoc的時候,所依賴的HTML模板文件就存放在這個目錄),以及一個用於Ant構建的示意XML配置文件,仔細瀏覽這個目錄下的文件,就可以對ASDOC有更好的瞭解。
  3. bin 按照慣例,我們基本也能猜出這個目錄下是什麼,沒錯,就是Flex SDK中包含的工具集(編譯工具,庫打包工具,文檔生成工具,以及優化工具等等,這些可都是Flex開發所必須的利器),這些工具的具體用法,我們會在後面的文章中介紹。建議您將這個路徑配置到系統用戶的PATH中,方便通過命令行調用相應的工具。
  4. frameworks 這個也是重中之重,包含了Flex框架的核心源碼(您應該也已經瞭解到,Flex是基於AS3的一個框架,其底層代碼均是由AS3編寫的(注:不包含工具集,工具是Java編寫)),當您在Flex編程中有疑惑,看一眼源碼或許會讓您茅塞頓開。
  5. include 包含了一個用於編寫ActionScript擴展的C++頭文件:FlashRuntimeExtensions.h,如果您基於AIR做一些嵌入式應用(比如一個電視機),需要實現換臺等功能,那就要用C++實現一些ActionScript的擴展。
  6. install 包含了用於移動開發的Android USB驅動程序
  7. lib 開發和編譯Flex應用所依賴的類庫,打開這個目錄您就能發現很多的JAR文件,比如mxmlc.jar,另外您可能已經注意到還有mxmlc_zh_CN.jar,顯然這些庫大都實現了本地化,方便我們的開發和調試。
  8. runtimes 包含運行時支持,但沒有Flash Player,只有AIR,包括AIR for Android的APK文件
  9. samples 一些實例文件,包括用於AIR在線無縫安裝的badge,和一些Flex主題。
  10. templates 包含一些模板文件,比如用於AIR應用描述的XML約束定義文檔,swfobject的示例代碼等等

因爲Flex框架是開源的,所以我們也可以不安裝Flash Builder,直接下載Flex的SDK。官方網站是:

http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK

裏面會有Flex SDK各個時期的版本,如無特殊需求,下載最新的正式版本即可。

這裏插播一段,Flex各個組成部分之間的開源關係(一些朋友可能會對這個方面有疑問)

  1. Flex框架:開源,包含Flex的類庫(UI庫,工具庫等,基於AS3),和語言(MXML和Action Script3)
  2. Flex SDK:包含開源的Flex框架和工具(編譯工具,優化工具等等,這些工具免費使用,但不開源)
  3. Flash Builder:商業IDE,包含Flex SDK,和提高開發者生產力的工具支持

基於字母排序,我們就從Ant着手,來了解Flex SDK。

Flex對Ant的支持

Ant的全稱是Apache Ant,是Apache基金會的一個子項目。它的設計目標是用於完成Java開發中的自動構建。如果您是Java開發者,那麼Ant對於您並不陌生,實際上Ant在Java社區中得到了極爲廣泛的應用。如果您並不是從Java開發轉向到Flex開發,還沒有過多接觸過Ant,那麼沒關係,Ant的概念和要解決的問題一定會讓您激動的熱淚盈眶(有點誇張,呵呵),因爲開發領域很多概念都是相似的,Java開發中遇到的問題,我們Flex開發者也會遇到很多,比如自動構建,在一個有着N多模塊,N處源碼,構建過程複雜的Flex項目開發中,依賴人力手工構建項目非常不現實(機械重複且枯燥無味的過程,相信哪位開發人員都會避之唯恐不及,而且對於人力是非常大的浪費),而通過使用Ant,我們可以將這些工作交給機器來做,機器最適合乾的就是這些程序固定,順次執行的工作,而且不辭辛苦,又快又好:)

如果你想先詳細瞭解一下Ant,請訪問Baidu文庫中對Ant的定義。這裏不再過多介紹。

下面我們來着重瞭解一下Flex對Ant的支持情況。打開Flex SDK下的Ant目錄,會看到下面的文件結構:

lib中包含了Flex對Ant的任務支持庫:flexTasks.jar,src目錄中包含了flexTasks的Java源碼,build.xml則是用於構建flexTasks本身的配置文件(如果您修改了flexTask的Java源碼,可以用這個配置文件,重新編譯,並打包到flexTasks.jar)。

README.txt這個文件則簡單描述瞭如何使用flexTask,筆者已經將它翻譯爲中文,即README_CN.txt,您可以從本文的頁面底部的下載區下載這個文件。

打開MxmlcTask.java,我們可以看到,這就是對mxmlc工具的任務封裝,方便我們在Ant中基於配置文件來調用mxmlc實現對Flex項目的編譯。

下面我們通過一個簡單的演示,來了解使用Ant編譯項目的過程:

1. 安裝

當然,首先您得安裝Ant,並完成必要的配置(添加路徑到系統用戶Path)。下載地址 | 安裝教程

安裝完畢後,打開CMD窗口,運行ant -version,如果能看到正確的輸入信息,就代表Ant配置成功了。

然後,將flexTasks.jar這個文件放到您的Ant安裝目錄中的lib目錄中。雖然也可以採取將JAR文件的地址作爲一個參數傳遞給Ant的方法,但爲了方便起見,推薦直接拷貝flexTasks.jar的方式。

另外,注意您想使用的構建工具(比如mxmlc或asc)必須包含在您的PATH設置裏。將sdk/bin這個目錄也配置到Path中,您的Path設置應該類似於下面的:

  1. C:\Program Files (x86)\Java\jdk1.6.0_25\bin;D:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0\bin;C:\ant\bin

請輸入下面的命令到CMD窗口:mxmlc -version,如果有正確的輸出,代表Flex SDK的路徑配置成功。

2. 測試

首先到您的磁盤便於尋找的位置,創建一個測試目錄,比如命名爲ant_test,裏面創建2個目錄:src和bin。src用於放置Flex源碼,bin用於放置輸出的SWF文件。然後創建一個MXML文件(隨便一個文本編輯工具就可以),命名(比如Main.mxml),放到src下面。代碼如下,非常簡單,顯示一個按鈕:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600">
  5. <s:Button x="52" y="25" label="按鈕"/>
  6. </s:Application>

然後爲了檢測ASDoc的生成效果,您可以在src目錄中隨意添加一個ActionScript的類,寫一些基於ASDoc規則的註釋,比如:

  1. package
  2. {
  3. import flash.display.Sprite;
  4.  
  5. /**
  6. * Test Class
  7. * <p>Hi Neo,come here <strong>hello</strong></p>
  8. * @author NeoGuo
  9. *
  10. */
  11. public class TestClass extends Sprite
  12. {
  13.  
  14. /**
  15. * UBB Code
  16. */
  17. public var ubb:String;
  18. private var _bbb:String;
  19.  
  20. public function TestClass(bbb:String="1")
  21. {
  22. super();
  23. this._bbb = bbb;
  24. }
  25.  
  26.  
  27. public function get bbb():String
  28. {
  29. return _bbb;
  30. }
  31.  
  32. public function set bbb(value:String):void
  33. {
  34. this._bbb = value;
  35. }
  36.  
  37. }
  38. }

然後創建build.properties,按照慣例,這是用Ant的變量配置文件(注意放在src的上一層,即ant_test目錄下),然後寫入以下的配置參數:

  1. # 設置到您的Flex SDK的所在路徑
  2. FLEX_HOME=D:/Program Files (x86)/Adobe/Adobe Flash Builder 4.5/sdks/4.5.0
  3.  
  4. # 定位到您的項目源碼的位置
  5. # {$basedir} 是Ant默認支持的變量
  6. SOURCE_DIR =${basedir}/src
  7.  
  8. # 定位到您的Lib路徑,如果存在的話
  9. LIBS_DIR =${basedir}/libs
  10.  
  11. # 設定SWF的輸出位置
  12. OUTPUT_DIR = ${basedir}/bin
  13.  
  14. SDK_VERSION = 4.5.0.20967
  15. LOCALE = en_US

然後開始編寫build.xml,如下所示,我在主要部分均做了註解:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <project name="test-flex" default="build">
  3. <!--引用屬性配置文件-->
  4. <property file="build.properties" />
  5. <!--定義任務的庫引用路徑,比如下面第25行我們用到了mxmlc,必須讓Ant知道去哪裏尋找這個任務的定義,包括類名稱和classpath。這裏我們配置了4個,實際上用到了3個,即調用mxmlc完成編譯,調用html-wrapper對SWF進行HTML包裹,調用asdoc生成代碼文檔。compc是用來編譯庫(SWC)文件,這裏我們沒有用到。 -->
  6. <taskdef name="mxmlc" classname="flex.ant.MxmlcTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
  7. <taskdef name="compc" classname="flex.ant.CompcTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
  8. <taskdef name="html-wrapper" classname="flex.ant.HtmlWrapperTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
  9. <taskdef name="asdoc" classname="flex.ant.AsDocTask" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
  10. <!--完成當前構建任務所需的4個調用,首先是清理,如果bin下面有文件,刪除掉;然後是編譯,HTML包裹,和ASDoc文檔生成-->
  11. <target name="build">
  12. <antcall target="clean"/>
  13. <antcall target="compile"/>
  14. <antcall target="wrapper"/>
  15. <antcall target="asdoc"/>
  16. </target>
  17. <!--執行清理-->
  18. <target name="clean">
  19. <delete includeemptydirs="true">
  20. <fileset dir="${OUTPUT_DIR}" includes="**/*"/>
  21. </delete>
  22. </target>
  23. <!--執行編譯,注意debug參數,默認是false,如果您需要開啓Debug功能,可以將它設置爲true(會增大文件體積)-->
  24. <target name="compile">
  25. <mxmlc
  26. file="${SOURCE_DIR}/Main.mxml"
  27. output="${OUTPUT_DIR}/Main.swf"
  28. locale="${LOCALE}"
  29. static-rsls="false"
  30. accessible="true"
  31. debug="false"
  32. >
  33. <!--加載Flex配置文件,如果您有特殊需求(比如要保留自定義的Metadata標籤,則可以設置自己定義的Flex配置文件)-->
  34. <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
  35. <!--設置源碼位置-->
  36. <source-path path-element="${SOURCE_DIR}"/>
  37.  
  38. <!--下面是對運行時共享庫RSL的配置,不是必須,如果您不採用RSL機制,可以刪除下面的定義;如果您沒用到一些RSL,可以刪除,只保留核心的framework, spark等引用-->
  39. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/framework.swc">
  40. <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"/>
  41. <url rsl-url="framework_${SDK_VERSION}.swz" policy-file-url=""/>
  42. </runtime-shared-library-path>
  43. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/textLayout.swc">
  44. <url rsl-url="http://fpdownload.adobe.com/pub/swz/tlf/2.0.0.232/textLayout_2.0.0.232.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  45. <url rsl-url="textLayout_2.0.0.232.swz" policy-file-url=""/>
  46. </runtime-shared-library-path>
  47. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/mx/mx.swc">
  48. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/mx_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  49. <url rsl-url="mx_${SDK_VERSION}.swz" policy-file-url=""/>
  50. </runtime-shared-library-path>
  51. <library-path file="${FLEX_HOME}/frameworks/libs/flash-integration.swc" append="true"/>
  52. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/rpc.swc">
  53. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/rpc_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  54. <url rsl-url="rpc_${SDK_VERSION}.swz" policy-file-url=""/>
  55. </runtime-shared-library-path>
  56. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/charts.swc">
  57. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/charts_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  58. <url rsl-url="charts_${SDK_VERSION}.swz" policy-file-url=""/>
  59. </runtime-shared-library-path>
  60. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/spark.swc">
  61. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/spark_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  62. <url rsl-url="spark_${SDK_VERSION}.swz" policy-file-url=""/>
  63. </runtime-shared-library-path>
  64. <library-path file="${FLEX_HOME}/frameworks/libs/authoringsupport.swc" append="true"/>
  65. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/advancedgrids.swc">
  66. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/advancedgrids_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  67. <url rsl-url="advancedgrids_${SDK_VERSION}.swz" policy-file-url=""/>
  68. </runtime-shared-library-path>
  69. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/sparkskins.swc">
  70. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/sparkskins_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  71. <url rsl-url="sparkskins_${SDK_VERSION}.swz" policy-file-url=""/>
  72. </runtime-shared-library-path>
  73. <runtime-shared-library-path path-element="${FLEX_HOME}/frameworks/libs/spark_dmv.swc">
  74. <url rsl-url="http://fpdownload.adobe.com/pub/swz/flex/${SDK_VERSION}/spark_dmv_${SDK_VERSION}.swz" policy-file-url="http://fpdownload.adobe.com/pub/swz/crossdomain.xml"/>
  75. <url rsl-url="spark_dmv_${SDK_VERSION}.swz" policy-file-url=""/>
  76. </runtime-shared-library-path>
  77. <library-path file="${FLEX_HOME}/frameworks/locale/${LOCALE}" append="true"/>
  78. <library-path file="${LIBS_DIR}" append="true"/>
  79. <!--因爲Flash Player內置的庫,不需要打包到SWF,所以對playerglobal採取了排除方式-->
  80. <external-library-path file="${FLEX_HOME}/frameworks/libs/player/10.2/playerglobal.swc" append="true"/>
  81. <library-path file="${FLEX_HOME}/frameworks/libs/flash-integration.swc" append="true"/>
  82. <library-path file="${FLEX_HOME}/frameworks/libs/authoringsupport.swc" append="true"/>
  83. <!--引用本地化的庫支持-->
  84. <library-path dir="${FLEX_HOME}/frameworks/locale/${LOCALE}" includes="*" append="true"/>
  85. <!--當前項目的庫引用位置-->
  86. <library-path dir="${LIBS_DIR}" includes="*" append="true"/>
  87.  
  88. </mxmlc>
  89. <!--如果基於RSL,爲了保證用戶在第一次使用RSL的時候,且鏈接不到Adobe服務器的情況下,保證應用可以正常運行,需要將這些Adobe簽名的RSL移動到項目的部署目錄下面。具體說明請參閱RSL的相關文章。-->
  90. <copy file="${FLEX_HOME}/frameworks/rsls/spark_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/spark_${SDK_VERSION}.swz"/>
  91. <copy file="${FLEX_HOME}/frameworks/rsls/charts_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/charts_${SDK_VERSION}.swz"/>
  92. <copy file="${FLEX_HOME}/frameworks/rsls/sparkskins_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/sparkskins_${SDK_VERSION}.swz"/>
  93. <copy file="${FLEX_HOME}/frameworks/rsls/framework_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/framework_${SDK_VERSION}.swz"/>
  94. <copy file="${FLEX_HOME}/frameworks/rsls/mx_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/mx_${SDK_VERSION}.swz"/>
  95. <copy file="${FLEX_HOME}/frameworks/rsls/textLayout_2.0.0.232.swz" tofile="${OUTPUT_DIR}/textLayout_2.0.0.232.swz"/>
  96. <copy file="${FLEX_HOME}/frameworks/rsls/spark_dmv_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/spark_dmv_${SDK_VERSION}.swz"/>
  97. <copy file="${FLEX_HOME}/frameworks/rsls/advancedgrids_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/advancedgrids_${SDK_VERSION}.swz"/>
  98. <copy file="${FLEX_HOME}/frameworks/rsls/rpc_${SDK_VERSION}.swz" tofile="${OUTPUT_DIR}/rpc_${SDK_VERSION}.swz"/>
  99.  
  100. </target>
  101. <!--執行對SWF進行HTML包裹,可以傳遞一些參數-->
  102. <target name="wrapper">
  103. <html-wrapper
  104. output="${OUTPUT_DIR}"
  105. file="Main.html"
  106. swf="Main"
  107. history="true"
  108. express-install="true"
  109. version-detection="true"
  110. version-major="10"
  111. version-minor="2"
  112. version-revision="0"
  113. height="100%"
  114. width="100%"
  115. title="Main"
  116. bgcolor="white"
  117. />
  118. </target>
  119. <!--執行ASDoc文檔生成-->
  120. <target name="asdoc">
  121. <asdoc output="${OUTPUT_DIR}/asdoc" lenient="true" failοnerrοr="false">
  122. <doc-sources path-element="${SOURCE_DIR}"/>
  123. <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
  124. </asdoc>
  125. </target>
  126.  
  127. </project>

然後就可以執行Ant了,如果您是Win7系統,在ant_test目錄上按住Shift點右鍵,選擇"在此處打開命令窗口",然後輸出ant,回車,就可以看到整個執行過程

等待編譯完成,您可以查看bin目錄下,生成了SWF文件,HTML文件,以及ASDoc文檔等等。特別是ASDoc,對於團隊協作的項目開發很有意義。

附件中的TestAnt.zip就是本次演示的打包下載。

Flash Builder對於Ant的支持

之前的Flash Builder,做了很多精簡,移除了Eclipse的Java開發插件,Ant也沒有保留,所以如果您使用的是Flash Builder4,是不能直接使用Ant的,需要下載Ant的插件(參閱這篇教程)。這樣還是給開發者造成了很多不便的。所以,在Flash Builder 4.5這個版本里面,已經內置了Ant的開發插件。如果您已經安裝了Flash Builder 4.5,請打開,隨便某個項目上點擊右鍵,屬性,構建器,然後在打開的窗口中點擊右側的新建按鈕,可以看到Ant Builder的選項。

默認情況下,項目只有一個Flex構建器(因爲筆者安裝了SourceMate插件,所以多了一個SourceMate構建器)。基於Ant,您可以很方便的爲項目添加其它的構建器,滿足多樣化的需求,比如您需要拷貝其它一些項目的模塊放置到您的項目進行聯合測試,而您又不想每次都手工操作,那麼可以通過這個面板,創建一個新的Ant Builder,指定一下構建所需的build.xml文件(具體語句不再闡述,請參閱Ant的相關文檔)即可。

SourceMate 3對於Ant的支持:

SourceMate是個Eclipse的商業插件,用於增強Flash Builder的功能,筆者從2.0開始使用,感覺很好,現在最新版本是3.0,針對Flash Builder 4.5做了一些功能變更(原有的一些代碼修復等功能因爲Flash Builder 4.5本身進行了增強,SourceMate刪除了與Flash Builder 4.5重複的功能,而在其它方面做了加強)。插件地址:

http://updates.elementriver.com/sourcemate/v3/

SourceMate對Ant有一個很不錯的功能,可以根據當前項目的配置,自動幫我們生成Ant構建文件(build.xml),這可以幫我們省不少事。該功能集成在SourceMate菜單中,如圖所示:

點擊"Generate Ant Build file",就可以生成build.xml,然後您可以根據自己的需要,稍加修改,即可用於項目的自動構建。

riadevID: 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章