除非你过去四年的编程生涯都是在五行山下度过的,否则必定对”富互联网应用”——或按潮人的叫法“RIA”——略有所闻。万一你真是如前所述的隐居型开发者,那我把重任交给Google,请它帮你找出RIA的正式定义。我们暂且把它定义成,具有在设计上更注重更操作性和效率的用户界面,不同于传统Web应用那种“输入地址,等待网络传输一个Web页面,填写表格,点击按钮,等待网络传输另一个Web页面”的交互循环。AJAX是一种RIA,Silverlight也是,但比它们出现早得多的,是Adobe的Flash。
因为新鲜感,对RIA的关注重心,大都集中在AJAX和老朋友JavaScript等工具。但是过去三年里,Apple迅速且戏剧化崛起,并在移动市场占有主导地位,对此产生了极大挑战。以最新的浏览器技术和宽带连接为前提来建立Web应用是不够的,因为连美国政府自己都做不到这两点。实际上,即使有最新的浏览器技术和最快的连接,只要开发人员打算用超越基本HTML的技术来开发Web应用,就会突然发现自己掉进了一个泥潭,互相冲突的浏览器实现、网络延迟、几十种JavaScript库、错估的用户预期,劈头盖脸而来。
起源…个人选择
作为一个职业生涯中大部分时间都在关注后端的开发者,我从来都不太关心前端开发者使用的工具和技术。实际上我曾经把前端贬得一文不值,说那一头的大部分开发”除了看看像素变颜色就没有什么了”。这话比较难听,我承认,但你也应该承认,除开最近几年,传统应用的UI设计一向不是业内的时尚话题:放个表单,用户填两下子,然后提交给服务器,实质工作都是我们后端人员做的。所谓实质工作包括:验证所有的输入(免得万一用户真的是一名黑客,企图用Telnet伪装浏览器来跳过所有”完美的”JavaScript验证逻辑);调用一些数据库和Web服务,说不定还是并行的;纠合一些模板技术或视图生成技术,准备好将要返回的各种HTML、CSS和JavaScript片段,组装起来;最后传输回去给浏览器渲染和显示。
多美好的时光。
不过最近有几件事情发生,迫使我重新认清UI行业的现状:
移动设备市场——iPhone、Android还有Windows Phone——火热到如果忽视它们就意味着从软件开发行业中退休。虽然我挺想提前退休的,不过短时间内经济上不可行,还有两个小孩要上大学呢。
说到孩子,我的大儿子非常热衷于成为一名游戏开发者,对父子携手完成一两个游戏构想也很有兴趣。当然,对于我们这些做“大事”、搞“企业”开发的人,游戏一般不是我们关心的主题……但是除了想多花点时间跟我儿子在一起,把应用”游戏化”的概念在网络经营和市场营销的圈子里正迅速走红,因此是值得多探讨一些。
说到游戏,游戏有许多有意思的情况:与传统基于表单的应用相比,它们有各种各样的沟通和展示需求。当然游戏不是个例——如果能加快响应速度,甚或实现离线使用,那么很多商业应用也会受益。不管我们多么希望可以假定每个用户有永久在线的宽带连接,严峻的现实是飞机上的互联网连接十分罕见,宾馆的ISP经常无缘无故消失,会议现场的无线连接太难以捉摸。事实上,公平地说,虽然我们在各种场合见到的网络连接多了,可是优质的的连接更难找了。
这种状况严重损害了传统浏览器客户端的效果。
最后,Adobe找到了我,问我是否有兴趣从一个Java开发者的角度探讨Flex,深入了解它并反馈结果。充分披露原则要求我申明他们付费让我写这批文章,但是基于个人诚实原则,其实我一直想找个借口来好好了解一下Flex,所以他们的邀请乐得我“屁颠儿屁颠儿的”,可以这么说。
所以,我的计划就是照他们的要求,在InfoQ设一个专栏,以Java从业人员的眼光(而不是艺术家打扮画Flash故事板的Web设计师的眼光)来介绍Flex,观察的角度不限于呆板的传统业务应用,还有各种不同的角度,包括游戏/游戏化,与已有的Java应用程序集成,以及作为移动设备客户端技术的适用性。
我们可以开始了吗?
入门
Flash平台(Flex的基础)几乎像浏览器一样普及,已经安装到全世界的浏览器中接近十年时间。它被当作一种透过浏览器向不知情大众强行送上可爱动画短片、视频剪辑和奇怪游戏的手段。多年以来,要想完成HTML规范规定之外的任何事情,这是除Java
Applet以外的唯一方法,而Java Applet的问题一点也不少。显然,Flash要求用户安装一个本地插件,但这是必要的代价,况且很多用户早就为了看跳舞仓鼠或者玩其他什么可爱游戏,已经下载安装过了。
不幸,很多开发者仍将Flash拒之千里,因为它最初是按照”创意”类用户的习惯设计的,采用了美工人员比较熟悉的概念,例如故事板、时间轴、动画效果等。完全没有什么表单栏、对象模型、核心验证逻辑组件之类的东西。这意味着,如果一位开发者想要利用这个平台,将不得不面对各种模样怪异的工具,陌生的术语,还有一帮子不灌可乐品咖啡的用户群。
除了外表的差异,Flash平台其实和它的Java表亲很相似,都有一个基于字节码的执行引擎,都被移植到多种平台。(从很多方面来看,如果Java“一次编写,处处运行”的口号没有那么多“如果”,真能在客户端成为现实,那差不多就应该是Flash插件的样子。)Flash执行.SWF(读作”swiff”)文件而不是.class或.jar文件,这种文件格式也像.class文件一样是公开的。而且几年前,Adobe通过Flex开发包进一步开放了Flash平台,提供Flex的目的是让开发者不需要使用面向美工人员的Flash工具,也能轻松地创建SWF。
因此,第一步是获取SDK,这个可以在Adobe的网站找到。稍微观察下就可以发现,Flex有几种下载,主要的不同点是授权协议模式
– 最大的”Adobe Flex SDK”包含若干基于Adobe自定开源协议的软件,有可能不被某些组织接受,所以Adobe提供了另一种下载”Open
Source Flex SDK”,基于MPL授权协议的。一般来说,除非你的组织有特殊严格要求,否则”Adobe
Flex SDK”完全适合研究和原型开发用途,但是如果想投入商业产品应用,那么需要请律师先看一下授权协议。我们将用最新发布的Flex
4.5 SDK来进行讲解;如果你还没有准备好,花点时间完成下载吧。
下载回来的SDK是一个简单的ZIP文件,解压到你硬盘中任何方便的位置,最好放到离其他开发工具近的地方。在我的系统里,我喜欢把所有工具都放在”prg”目录下,所以Flex
SDK在我的Windows电脑里就放在”C:\Prg\flex-4.5″的位置;请看图1-1。在该目录下存放了一系列工具和文件,看过JDK目录的开发者会觉得它的目录结构很熟悉。”bin”目录存放着开发者心爱的各种工具(所以应该将其路径放进“PATH”环境变量),”samples”目录下有各种示例应用,还有其他目录就不一一说明了。
图1-1
(提醒:看看图1-1中列出来的目录,文件”env.bat”是我自己创建的,用于快速设置Flex命令行开发环境。它是一个简单的批处理文件,里面设置PATH环境变量和终端窗口标题,在Windows下其内容如图1-2。它假定同一个终端窗口下已经配置好JDK和相关工具。)
图1-2
[blockquote]@SET ANT_HOME=C:\prg\apache-ant @SET JAVA_HOME=C:\prg\jdk_1.6.0 @SET FLEX_HOME=C:\prg\flex_sdk_4.5.0.20967 @PATH=%FLEX_HOME%\bin;%ANT_HOME%\bin; %JAVA_HOME%\bin;%PATH% @TITLE Flex 4.5 Prompt[/blockquote] |
检验Flex是否已经安装好,最快最简单的办法是运行一下”bin”里面的一个工具——mxmlc,也就是我们马上就会认识的Flex编译器。所以,假设
C:\Prg\flex-4.5\bin已经加到PATH变量,直接输入”mxmlc”,看看有没有反应;如果一切都没问题,你就会看到传统编译器”我其实没有做任何事情”的响应,看图1-3。
图1-3
代码拿来(还有工具)!
开发者遇到新平台,写的第一个程序必然是”Hello World”,不仅是向先驱(Kernighan和Ritchie)致敬,也因为它展示了我们可以用新平台写出的最简单的程序。对于某些平台,像最初的C编译器,只要三行文本和一次命令行调用就完成了一个有意义的可执行程序;当平台变得更复杂,构建的步骤也越来越复杂。(Java开发者回想起“Hello,EJB!”所需的步骤,依然会不寒而栗。)Flex还是比较简单的,虽然不至于只用一个文本文件就变出花来。
先搭脚手架
Flex和Flash之间的关系非常像Java和JVM — Flex是一个工具(一整套SDK,如果我们准确完整描述的话),用于生成字节码,然后和资源一起打包成适合在Flash平台上运行的.SWF文件。按照Flash的执行方式,它需要某种执行引擎或者叫虚拟机来执行SWF文件。一般来说,当遇到SWF文件时,用户机器上已经安装好必要引擎/VM,但也不一定;因此,要么让用户提前安装Flash平台,要么开发者在第一次运行的时候为用户即时安装平台。
从实际操作来说,前一段描述可以这么总结:对于Web应用程序,SWF文件需要某种类型的HTML脚手架来帮助它“导入”Flash
VM,很像Java applet加载JVM的情况。以前用applet的时候,要告诉浏览器”这儿有一个applet”,然后说明JAR文件的位置,最后启动正确的类。Flash的所用的HTML脚手架与此类似,见代码段2-1,它告诉浏览器”这儿有一个Flash”,然后指明要加载的SWF以及相关的具体环境。
代码段 2-1
<html> <body> <object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase= "http://active.macromedia.com/flash2/cabs/swflash.cab#version =4,0,0,0" width="1024" height="768"> <param name="movie" value="MyFirstFlex4App.swf" /> <embed src="MyFirstFlex4App.swf" width="1024" height="768" pluginspage= "http://www.macromedia.com/shockwave/download/index.cgi? P1_Prod_Version=ShockwaveFlash" /> </object> </body> </html> |
我们暂时可以忽略例中的大部分HTML基本骨架——关键元素在中间部分即<OBJECT>标签下的<EMBED>子标签。显而易见,”src”属性指定当在页面被浏览器加载显示时,被执行的SWF文件名。<PARAM>标签描述该SWF文件所在的URL;因为我们是在本地文件系统操作,所以该属性与<OBJECT>中的”src”属性完全相同。”width”和”height”属性的作用是不言而喻的。所有这些在Adobe的网站上有详细的描述,想了解所有标签的用途和可能参数的读者,请看这个链接还有这个链接。(简单补充一下,<OBJECT>是给IE3.0看的,<EMBED>是给Netscape
Navigator2.0看的。是的,Flash有这么老。)
有心人可以在浏览器里打开这个页面,看看会得到什么结果。虽然没多大看头,但是当作一个快速测试,检查一下机器上是否已经安装好了Flash插件。虽然这检查有点多余,不过万一真的没装,现在是一个很好的下载时机。
64位?别提了,我说!别提了!
一句话说明Flash Player和64位浏览器的关系:它俩合不来。具体来说,Flash还不支持64位浏览器,所以尝试在64位浏览器中运行Flash一定会失败。Adobe回应说,”用32位版的浏览器算了,反正大家都用”,以及”将支持64位”,请参考这里。
水印和代码
Flex就像HTML一样,是一种双管齐下的工具。一方面 ,开发者用标记语言(Flex用的标记语言是XML)来描述程序中的各种按钮、控件……以此完成用户界面组件的布局工作。如果只是显示一句静态的“hello,
world”文本,那么只用标记语言就能轻松完成。不过, Flex还有另一面,你还可以用它编写代码来响应各种控件触发的事件,而这些才是在开发人员用来完成“实际工作”的手段。为了演示这一面,我们来做一个稍稍复杂一点的例子
:在页面上创建一个按钮,然后用一个事件处理器来响应按钮事件并弹出一个消息框显示“Hello world”字样。
Flex编译器mxmlc的处理对象是带“MXML”扩展名、以文本格式存储的标记语言脚本,所以请打开你信赖的文本编辑器,创建一个“MyFirstFlex4App.mxml”文件。(做好用一个能够理解XML语法的编译器,以避免类似忘记结束标记等明显的XML错误。)输入如代码段
2-2所示的标记语言脚本。这只是一个入门例子,不要求理解其中的细节,只是让你体会一下语言和环境的总体感觉,顺便检查一下工具和运行时是否配置无误。
代码段2-2
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"> <s:Button x="17" y="14" label="Button" id="btnSayHello" /> </s:Application> |
MXML文件本身就是一种合乎规格的XML文件,所以里面的XML命名空间跟一般的XML命名空间并无不同,即限定不同的标记名称的语法作用域。可以把这些命名空间当作Java包的角色来看待。代码中声明的一长串命名空间前缀,实际我们只用到其中两个,fx:(下一个例子会用到)和s:。多数Flex程序都喜欢把这一串命名空间写全,因为声明额外的命名空间不会对最后生成的程序有任何影响(就像导入未使用的Java包),所以可以算作一种好习惯,至少目前如此。
其余的标记比较简单明了:”s:Application”标签说明这是一个应用程序,它包含一个子控件”s:Button”。只要曾经编写过HTML表单,就不会对这几个标签的属性感到陌生,这是故意设计的。我们还没有说明按钮被点击时会做什么,但本着“早发布,常发布”的精神,我们先运行一下看看
。
在我的机子上怎么运行不了!
如果什么都没显示,或者出于某种原因,您的浏览器开始从Adobe下载软件,请勿慌张;先前搭建的HTML脚手架正在替用户忙碌,从Adobe网站上下载最新的Flash播放器。这一迹象表明你的机器还没有安装Flash播放器,等待几分钟,点击几个“你确定吗?”对话框,Flash就应该准备好了。
还有问题的话,请访问<<Adobe的网址>>以验证Flash是否已经正确安装。如果还失败,你可能需要联系您的系统管理员去排除故障,这超出了本文所讲的范围。
构建
构建Flex应用程序必不可少的步骤是用mxmlc工具将 MXML文件编译成 SWF文件。假设mxmlc已经存在路径中,且.mxml文件在同一目录,执行“mxmlc
MyFirstFlex4App.mxml”,命令行编译器万年不变的工作过程就开始了 :它会回馈说明当前执行到的步骤,如果代码正确无误,执行完毕的时候目录下就会多出来一个新生成的.swf文件。如果我们再次在浏览器中打开先前的HTML脚手架文件,等Flash插件加载完毕,就可以看到如图2-3的内容。现在的页面内容仍然没什么看头,因为当用户(你、我、或者刚好经过的大姨妈Sally)点击按钮时没有任何反应。
图2-3
代码
大姨妈Sally来早了——不管她怎么点击按钮都没有任何反应,Sally很失望。修正这个问题,只要给按钮的”onClick”事件定义一个事件处理器就可以了,跟编写HTML表单是一样的。这是为了贴近Web开发而故意仿造了HTML的设计,用来编事件处理程序的语言也非常像JavaScript,名为ActionScript,熟悉它的开发者常简称为AS。
对于简单的示例,直接把AS写在标记文件中比较简单,所以请打开刚才的.mxml文件,然后把代码段2-4插入其中。有两个地方做了修改:”<fx:Script>”子标签下定义了事件处理函数,按钮的”click”属性声明了用户点击时将要执行的函数。如果您不熟悉”CDATA”标签,我稍作解释:它是一个特殊的XML标记,用来告诉XML解析器停止将”<”等标签分隔符当作标签分隔符来处理;不然在标记文件中写代码会非常麻烦,尤其是当有比较和布尔操作符(“<”和”&”)的时候,因为需要对它们进行XML转义编码。(对不起,各位,但是”if
(1 < 5)”和”if (x &&| y)”真的不太易读。)
代码段2-4:
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"> <fx:Script> <![CDATA[ import mx.controls.Alert; protected function btnSayHello_clickHandler(event:MouseEvent):void { Alert.show("Hello World"); } ]]> </fx:Script> <s:Button x="17" y="14" label="Button" id="btnSayHello" click="btnSayHello_clickHandler(event)"/> </s:Application> |
有经验的JavaScript用户会很快注意到JavaScript和ActionScript的一些不同之处;Adobe选择脱离传统的JavaScript,尝试解决对JavaScript语言的一些常见批评。例如,ActionScript比JavaScript有更严格的类型,所以AS的声明语句要求有”类型描述符”,帮助编译器确认没有用错对象。ActionScript在使用一个包(库)之前,先要进行引用,所以例中脚本块的开头有一行”import”语句。
函数的命名就像JavaScript一样没有什么规定,只是按照惯例写成”control_handler”的格式,如果这不符合你的编码习惯,请随意更改。(只是之后不要抱怨。)
重新编译代码产生一个新的SWF,现在可以响应按钮点击了,在浏览器中重新载入”hello.html”页面,点击按钮会产生图2-5的结果。编程前辈们,接受我们的Hello
World致意吧!
图2-5
重复的工作
只要是写过5分钟Java代码的开发者,都知道Ant构建工具的好处——让人类从事任何重复工作都是在等着出错而已,随之而去还有生产力和发展势头。(如果你从来没有浪费过时间在调试上,从来没有遇到过编译失败,那就请你从本系列的下一篇文章开始看吧。)因为Flex是像Java一样的综合开发环境,显然应该有一个与Ant角色地位相当的工具,Adobe做得更好:他们没有重复造轮子,而是让Flex提供一系列Ant任务插件,让Java/Flex开发者易于将Flex集成到他们构建脚本中。
(是的,这意味着你需要安装Ant,无论作为IDE一部分还是直接从命名行运行都可以(请参考这里)。如果你居然没有安装Ant,请自动摘下Java开发者的牌子,回去弄你的COBOL吧,我们会装作什么都没有看到。如果喜欢用Maven,那就要靠自己了——Adobe没有提供现成的支持。尽管你可以找到一些教程说明如何把Flex
SDK安装到Maven仓库,但老实说,如果你使用Maven……叫救命罢。马上。)
计划
我们有两个源文件,MyFirstFlex4App.mxml是“真正的”Flex布局和代码,还有一个hello.html是HTML脚手架,用来显示编译好的Flash应用程序。通常情况下,Java惯例建议把所有代码文件放到项目根目录下的”src”目录,如果你还没有这么做,创建这个子目录然后把文件都放到这里吧。为了确保新的配置仍然有效,作为测试,再次启动mxmlc,从”src”目录构建.SWF文件,生成的输出文件再存放回该目录,请输入以下命令:”mxmlc
src/MyFirstFlex4App.mxml “。当然,传统惯例是把生成的文件放到另一个目录(最起码使清理各种生成物更容易),mxmlc同样支持此惯例,加上“output”命令行参数就可以了:”
mxmlc src/MyFirstFlex4App.mxml -output dist/MyFirstFlex4App.swf”。
如果一切正常,我们就把上面的命令行转化成一个Ant构建文件。虽然用Flex提供的几个构建任务来编写可以使这个文件更简单,但我们还是循序渐进吧。直接用<exec>任务来编写,得到如代码段3-1的Ant文件,。
代码段3-1:
<project name="MyFirstFlex4App" basedir="." default="compile"> <target name="init"> <mkdir dir="build" /> <mkdir dir="dist" /> </target> <target name="compile" depends="init"> <exec executable="mxmlc"> <arg value="src/MyFirstFlex4App.mxml" /> <arg value="-output" /> <arg value="dist/MyFirstFlex4App.swf" /> </exec> </target> <target name="clean"> <delete dir="build" /> <delete dir="dist" /> </target> </project> |
Flex任务
当然,使用<exec>标签最大的缺点是,我们不得不给每个参数都安排一个<arg>标签,参数多的话实在令人乏味。另外,对于写出来的Ant任务是否正确,我们没有任何验证手段,所以换成Adobe提供的Ant任务还是有好处的。替换工作非常简单,添加一个Ant<taskdef>导入Flex任务,然后改由Flex提供的任务元素去执行编译。
这里有个小提醒:按照Flex SDK的”Ant” 目录下README文件的说明,Flex提供的Ant任务要求把Flex工具放到PATH环境变量,才能正确执行。既然我们一直以来都在用命令行构建,这应该不是一个问题;但如果之后用Ant构建出了问题,请检查这项设置。
切换到使用<mxmlc>任务,只要简单地把<exec>改成<mxmlc>,然后把命令行参数套用为同名的属性,如代码段
3-2所示。改成Flex任务之后代码变短了,因为现在编译参数被写成属性而不是<arg>子标签。
代码段3-2:
<target name="compile" depends="init"> <mxmlc file="src/MyFirstFlex4App.mxml" output="build/MyFirstFlex4App.swf" /> </target> |
搭建Ant脚手架
还差一个步骤才能让<mxmlc>正确执行,那就是告诉Ant在哪里可以找到 Flex任务。这是Ant<taskdef>标签的工作,它需要引用”flexTasks.jar”文件,各种Ant任务就定义在这个文件里;还要引用”flexTasks.tasks”
文件,这个文件把标签名称(“mxmlc”)映射到JAR文件中对应的Java类(“flex.ant.MxmlcTask”)。假设Flex安装在系统中C:\Prg\flex4.5,<taskdef>就应该写成像”<taskdef
resource =”flexTasks.tasks” classpath=”C:/Prg/flex4.5/ant/lib/flexTasks.jar”
/>”。当然,在你的机器上Flex不一定安装在同样位置(特别是如果您用Mac或Linux的话),这意味着,如果我们都在做同一个项目,马上就会有人感到沮丧:你的”/usr/local/flex-4.5″和我的”C:\Prg\flex-4.5″不可能妥协。如果在Ant脚本中直接嵌入Flex
SDK的安装目录,那就只有”两个只能活一个”的办法才能解决问题。
Ant用了属性文件来解决这个冲突:定义一个处于源代码控制之外的本地文本文件,名为“local.properties”,在文件中定义一个形如“name=value”的键值对:”FLEX_HOME=<任意的安装位置>”。然后把taskdef标签改写成”<taskdef
resource=”flexTasks.tasks” classpath=”${FLEX_HOME}/ant/lib/flexTasks.jar”/>”,这样就皆大欢喜了。
接下来就可以用上<mxmlc>了,如代码段3-3所示。
代码段3-3:
<project name="MyFirstFlex4App" basedir="." default="compile"> <property file="local.properties" /> <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" /> <target name="init"> <mkdir dir="build" /> <mkdir dir="dist" /> </target> <target name="compile" depends="init"> <mxmlc file="src/MyFirstFlex4App.mxml" output ="build/MyFirstFlex4App.swf" compiler.debug="true" /> </target> <target name="clean"> <delete dir="build" /> <delete dir="dist" /> </target> </project> |
是的,这就是一段没意思的Ant代码,但现在打好基础将来会有回报。写好这段Ant脚本,以后所有的Flex项目都可以用它来做模板,就像当初servlet还新鲜的时候,我们给Java/web-app写的Ant脚本一样。
顺便一提,好奇的读者如果想了解编译器命令行参数的完整列表,请输入”mxmlc -help”即可,这个列表同时也是<mxmlc>标签属性的完整列表。Adobe在FlexSDK/ant目录下的README文件中说明,编译器参数直接对应Ant任务的属性。因此,如果我们想启用命令行参数”-
compiler.debug”,就给<mxmlc>任务加上一个属性,”compiler.debug=’true’”。
嗯,还行。就是有点小问题。
包装
问题当然就是,”hello.html”脚手架文件仍然存放在”src”目录下,为了得到一个完整的构建产物,它应该和.SWF文件放到一起(反过来把.SWF文件搬来和它放在一起也行,如果你乐意)。虽然我们可以直接用<copy>把文件从”src”搬到”dist”(生成到“build”目录下的.SWF文件也照此办理,这样的目录结构是Ant惯例),但其实有一种更好的办法。
Flex提供的几种Ant任务之中,有一个<html-wrapper>任务,顾名思义用于生成HTML脚手架文件。事实上,它会产生一个非常充实的脚手架文件,生成一段用来自动检测浏览器能力的JavaScript代码,等等。任务生成的index.html和swfObject.js两个文件,本文没有足够的篇幅详细解说,简而言之,这个脚手架比之前的”hello.html”要全面的多,因此是更好的选择。况且用Ant来生成这个脚手架一点都不费力气,如代码段3-4所示。
代码段3-4:
<project name="MyFirstFlex4App" basedir="." default="compile"> <property file="local.properties" /> <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" /> <target name="init"> <mkdir dir="build" /> <mkdir dir="dist" /> </target> <target name="compile" depends="init"> <mxmlc file="src/MyFirstFlex4App.mxml" output ="build/MyFirstFlex4App.swf" compiler.debug="true" /> </target> <target name="dist" depends="compile"> <copy file="build/MyFirstFlex4App.swf" todir="dist" /> <html-wrapper title="Hello, Flex" height="640" width="480" swf="MyFirstFlex4App" output="dist" /> </target> <target name="clean"> <delete dir="build" /> <delete dir="dist" /> </target> </project> |
总结
从入门到出师,还有很长的路要走:我们还要讨论两套UI组件、输入事件、远程通信、库,还要学一种完整的语言(ActionScript),学过这些基础之后,才真正进入到有意思的主题,例如动画、游戏(我个人的最爱)和移动设备(有争议的主题)等等。幸运地是,我有充足的时间时间慢慢写,Adobe也有足够的预算来让我做这件事,所以这篇文章仅仅是“从Java开发者的角度学习Flex和Flash”系列短文的第一篇。日后我们会逐一介绍Flex和Flash所提供的一切。 |