转自:http://www.jexchen.com
大家都知道,我们在编写Flex应用程序时,通常是以
通常我们所说的Flex应用程序,本质上来说是基于Flex框架、采用ActionScript 3.0编写的Flash应用程序,从这一点来说,它和普通的Flash应用程序没有任何差别。相对来说,传统的使用Flash IDE(如Flash CS3)创建Flash程序时更多的基于“时间线”(Timeline)及“帧”(Frame)的概念,更易于设计师理解;而基于Flex框架来创建的 Flash应用程序更多是强调程序性,很少提及“时间线”与“帧”的概念,更易于程序员理解。其实Flex应用程序一样也有时间线,只是这部分由Flex 框架隐藏起来了,通常不为大家所熟悉,在默认创建Flex程序时,这一切Flex已帮我们完成了,但了解这部分内容更有助于大家对Flex应用程序的启动有更深刻的认识,以便能对程序更灵活的控制与发挥~~
我们来看看上面这幅示意图,Flex应用程序共由两帧组成,第1帧为preloader部分,第2帧为主应用程序部分,此两部分由Flex应用程序的根SystemManager统管,SystemManager是flash.display.MovieClip的子类,影片剪辑(movie clip)支持帧。由于swf属于一种渐进式(progressive)下载的格式,正是由于swf格式这个特性,Flash Player并不需要等待整个程序下载完成便可直接访问已载入帧的内容,因此第一帧通常用来作为应用程序载入时的loading画面显示,一般来说,第一帧包含的内容应该尽可能的少(在第一帧中尽量不要含有Flex框架的组件),以便能很快的下载并立即显示;第二帧才是主应用程序真正的内容,一旦 SystemManager实例进入到第二帧后,即开始内部主应用程序运行的生命周期(life cycle),也就是进入我们最为熟悉的
在程序进入第2帧,主程序application开始运行后,便会相应的触发相应的一系列事件,按事件发生的先后顺序依次来介绍:
preinitialize
应用程序application已实例化,但此时还未创建任何相关的孩子组件(child component)
initialize
此时,创建了相应的孩子组件,但还未对这些子组件进行布局
creationComplete
应用程序application完成全部实例化,并完成所有子组件的布局
apllicationComplete
上面三处事件的完成,表明application内部启动的整个进程完成,接下来便会通知SystemManager派发applicationComplete事件。此时,启动程序启动完成并准备运行。
Flash包含的是一个时间线上的多个帧, 而Flex的SWF只包含2个帧. SystemManager, Preloader, DownloadProgressBar和少量工具类都在第一帧, 剩下的包括应用代码/ 内嵌资源全都在第二帧中. 当Flash Player下载下载SWF时, 只要接收到第一帧内足够的数据, 就会实例化SystemManager, 由它来创建Preloader, 然后创建DownloadProgressBar, 这两个对象会察看剩余字节的传输过程. 当第一帧的所有字节传输完毕后, SystemManager发送enterFrame到第二帧, 然后是其他事件. 最后Application对象派发applicationComplete事件.
SystemManager是Flex应用的主控者, 它控制着应用窗口, Application实例, 弹出窗口, cursors, 并管理着ApplicationDomain中的类. SystemManager是FlashPlayer实例化的第一个类, 它存储了主应用窗口的大小和位置信息, 保存其子组件比如:浮动弹出窗口和模态窗口的痕迹. 通过SystemManager可以获得内嵌字体,样式和document对象.
自定义的可视化组件(UIComponent的子类)只有在调用过addChild()后, 才会有一个SystemManager赋给他们, 之前是Null. 所以在自定义可视化组件的构造函数中不要使用SystemManager.
通常, Application对象创建时, 发生如下事件:
1. 实例化Application对象
2. 初始化Application.systemManager
3. Application在初始化过程之前, 派发预初始化事件.
4. 调用createChild(). 此时, 所有应用组件被创建, 所有组件的createChild()被调用.
5. Application派发初始化事件, 表明所有的组件初始化完毕.
6. 派发creationComplete事件
7. Application对象添加到显示列表中
8. 派发applicationComplete事件
大多数情况下, 我们使用
Flex 是一个事件驱动的编程模型, 任何事情的发生, 其背后必然存在一个事件. 而开发者第一次看到MXML时, 很难体会到一个Xml标记的应用的事件流和实例化的生命周期. 这个对于HTML和Flash的开发者尤其会感到困惑, 因为其熟悉的方式与Flex的一点也不相似. HTML的实例化是从上到下的, Flash的执行是从Frame0开始一帧帧运行的. 而Flex则又有不同.
我们来看一个简单的MXML的应用.
1.
2.
4. layout="absolute"
5. backgroundGradientColors="[#67cbff, #fcffff]"
6. color="#000000"
7. fontSize="12"
8. preinitialize="report( event , 'preinitialize' )"
9. initialize="report( event , 'initialize' )"
10. creationComplete="report( event , 'creationComplete' )"
11. applicationComplete="report( event , 'applicationComplete' )"
12. >
13.
14.
15. 16.
17. [Bindable]
18.
19. public var outTextData:String="";
20.
21. public function report( event:Event , value:String ):void
22. {
23. outTextData += String( flash.utils.getTimer() ) + 'ms >> '
24. + event.currentTarget + '.' + value + '
';
25. }
26.
27. ]]>
28.
29.
30.
32. text="{ outTextData }"
33. right="10" left="10" top="50" bottom="10" alpha="0.5"
34. wordWrap="false"
35. initialize="report( event , 'initialize' )"
36. creationComplete="report( event , 'creationComplete' )"
37. />
38.
39.
41. id="HelloButton"
42. label="Say Hello"
43. initialize="report( event , 'initialize' )"
44. creationComplete="report( event , 'creationComplete' )"
45. rollOver="report( event , 'rollOver' )"
46. rollOut="report( event , 'rollOut' )"
47. click="report( event , 'click > Hello!' )"
48. />
49.
50.
52. label="Say Goodbye"
53. y="10" left="10" height="30" width="150" color="#000000"
54. initialize="report( event , 'initialize' )"
55. creationComplete="report( event , 'creationComplete' )"
56. click="report( event , 'click > Goodbye!' )"
57. />
58.
59.
61. label="Clear"
62. y="10" left="326" height="30" color="#000000" right="10"
63. initialize="report( event , 'initialize' )"
64. creationComplete="report( event , 'creationComplete' )"
65. click="outTextData='';report( event , 'click' )"
66. />
67.
68.
这个应用运行时, 输出了实例流程和事件流. 这校我们就能够看到所有事件的触发顺序. 可以发现应用启动后, 事件的顺序是一定的. 下面是输出的内容:
1. 167ms >> EventFlow0.preinitialize
2. 183ms >> EventFlow0.outTextArea.initialize
3. 187ms >> EventFlow0.HelloButton.initialize
4. 188ms >> EventFlow0.GoodByeButton.initialize
5. 189ms >> EventFlow0.ClearButton.initialize
6. 189ms >> EventFlow0.initialize
7. 243ms >> EventFlow0.outTextArea.creationComplete
8. 243ms >> EventFlow0.HelloButton.creationComplete
9. 243ms >> EventFlow0.GoodByeButton.creationComplete
10. 244ms >> EventFlow0.ClearButton.creationComplete
11. 244ms >> EventFlow0.creationComplete
12. 246ms >> EventFlow0.applicationComplete
13. 一旦applicationComplete事件触发后, 组件就会在鼠标事件派发后触发自己的事件.
14. 1807ms >> EventFlow0.HelloButton.rollOver
15. 2596ms >> EventFlow0.HelloButton.rollOut
16. 2954ms >> EventFlow0.HelloButton.rollOver
17. 3170ms >> EventFlow0.HelloButton.rollOut
18. 3543ms >> EventFlow0.HelloButton.rollOver
19. 4052ms >> EventFlow0.HelloButton.click > Hello!
20. 4267ms >> EventFlow0.HelloButton.click > Hello!
21. 4474ms >> EventFlow0.HelloButton.click > Hello!
22. 4569ms >> EventFlow0.HelloButton.rollOut
23. 4907ms >> EventFlow0.GoodByeButton.click > Goodbye!
24. 5130ms >> EventFlow0.GoodByeButton.click > Goodbye!