Flex application創建順序(轉)

>preinitialize->initialize->creationComplete->applicationComplete,
preinitialize在所有的初始化之前觸發,沒有子組件的定義,但是可以引用組件的變量.
initialize當所有子組件生成完成後觸發,在這個時間點還沒有組件被渲染出來.
creationComplete組件定義完成並已經在顯示列表.
applicationComplete所有的組件初始化完成並顯示.

首 先介紹一下SystemManager. 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事件

大 多數情況下, 我們使用<mx:Application>來創建application對象, 但如果使用ActionScript來創建的話, 那麼建議不要在application的構造函數中創建組件, 推薦在crateChildren函數中, 主要是從性能方面考慮.

Flash包含的是一個時間線上的多個幀, 而Flex的SWF只包含2個幀. SystemManager, Preloader, DownloadProgressBar和少量工具類都在第一幀, 剩下的包括應用代碼/ 內嵌資源全都在第二幀中. 當Flash Player下載下載SWF時, 只要接收到第一幀內足夠的數據, 就會實例化SystemManager, 由它來創建Preloader, 然後創建DownloadProgressBar, 這兩個對象會察看剩餘字節的傳輸過程. 當第一幀的所有字節傳輸完畢後, SystemManager發送enterFrame到第二幀, 然後是其他事件. 最後Application對象派發applicationComplete事件.

Flex 是一個事件驅動的編程模型, 任何事情的發生, 其背後必然存在一個事件. 而開發者第一次看到MXML時, 很難體會到一個Xml標記的應用的事件流和實例化的生命週期. 這個對於HTML和Flash的開發者尤其會感到困惑, 因爲其熟悉的方式與Flex的一點也不相似. HTML的實例化是從上到下的, Flash的執行是從Frame0開始一幀幀運行的. 而Flex則又有不同.

從我們開始學習Flex時, 我們就需要了解事件流和MXML的實例化.
我們來看一個簡單的MXML的應用.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute"
    backgroundGradientColors="[#67cbff, #fcffff]"
    color="#000000"
    fontSize="12" 
    preinitialize="report( event , 'preinitialize' )"
    initialize="report( event , 'initialize' )"
    creationComplete="report( event , 'creationComplete' )"
    applicationComplete="report( event , 'applicationComplete' )"
    >

    <mx:Script>
        <![CDATA[               
            [Bindable]
            public var outTextData:String="";
public function report( event:Event , value:String ):void
{
   outTextData += String(flash.utils.getTimer()) + 'ms >> '+ event.currentTarget + '.' + value + '\n';
}

]]>
    </mx:Script>

    <mx:TextArea
        id="outTextArea"
        text="Unknown macro: { outTextData }"
        right="10" left="10" top="50" bottom="10" alpha="0.5"
        wordWrap="false"
        initialize="report( event , 'initialize' )"
        creationComplete="report( event , 'creationComplete' )"
        />

    <mx:Button
        y="10" height="30" left="168" width="150"
        id="HelloButton"
        label="Say Hello"
        initialize="report( event , 'initialize' )"
        creationComplete="report( event , 'creationComplete' )"
        rollOver="report( event , 'rollOver' )"
        rollOut="report( event , 'rollOut' )"
        click="report( event , 'click > Hello!' )"
        />
       
    <mx:Button
        id="GoodByeButton"
        label="Say Goodbye"
        y="10" left="10" height="30" width="150" color="#000000"
        initialize="report( event , 'initialize' )"
        creationComplete="report( event , 'creationComplete' )"
        click="report( event , 'click > Goodbye!' )"
        />
       
    <mx:Button
        id="ClearButton"
        label="Clear"
        y="10" left="326" height="30" color="#000000" right="10"       
        initialize="report( event , 'initialize' )"
        creationComplete="report( event , 'creationComplete' )"
        click="outTextData='';report( event , 'click' )"
         /> 
</mx:Application>
這個應用運行時, 輸出了實例流程和事件流. 這校我們就能夠看到所有事件的觸發順序. 可以發現應用啓動後, 事件的順序是一定的. 下面是輸出的內容:
Unknown macro: 1287ms >> aa0.preinitialize
1310ms >> aa0.outTextArea.initialize
1315ms >> aa0.HelloButton.initialize
1318ms >> aa0.GoodByeButton.initialize
1321ms >> aa0.ClearButton.initialize
1321ms >> aa0.initialize
1407ms >> aa0.outTextArea.creationComplete
1407ms >> aa0.HelloButton.creationComplete
1407ms >> aa0.GoodByeButton.creationComplete
1407ms >> aa0.ClearButton.creationComplete
1407ms >> aa0.creationComplete
1411ms >> aa0.applicationComplete

一旦applicationComplete事件觸發後, 組件就會在鼠標事件派發後觸發自己的事件.

77264ms >> aa0.ClearButton.click
80605ms >> aa0.HelloButton.rollOver
81288ms >> aa0.HelloButton.click > Hello!
82214ms >> aa0.HelloButton.rollOut
85015ms >> aa0.GoodByeButton.click > Goodbye!

關於creationComplete事件的發生時機,手冊中是這樣說的:
    假設程序中有這樣的結構:

Application
    OuterVBox
        InnerVBox1
            InnerVBoxLabel1
        InnerVBox2
            InnerVBoxLabel2 

    事件:preinitialize, initialize, creationComplete發生的順序是這樣的:

OuterVBox preinitialize
    InnerVBox1 preinitialize
        InnerVBox1Label preinitialize
        InnerVBox1Label initialize
    InnerVBox1 initialize
    InnerVBox2 preinitialize
        InnerVBox2Label preinitialize
        InnerVBox2Label initialize
    InnerVBox2 initialize
OuterVBox initialize
        InnerBox1Label creationComplete
        InnerVBox2Label creationComplete
    InnerVBox1 creationComplete
    InnerVBox2 creationComplete
OuterVBox creationComplete 

    所有的initialization事件完成後,creationComplete時間纔開始發生,先從葉子控件開始,然後是他們的父控件,直到application。

    如果將 OuterVBox容器變成ViewStack並且creationPolicy 屬性爲auto, 則事件發生順序是:

OuterViewStack preinitialize
    InnerVBox1 preinitialize
    InnerVBox2 preinitialize
OuterViewStack initialize
        InnerBox1Label preinitialize
        InnerBox1Label initialize
    InnerVBox1 initialize
        InnerBox1Label creationComplete
    InnerVBox1 creationComplete
OuterViewStack creationComplete 

然而,對於item renderer 或者 item editor, Flex 可能會重用item renderer 或者item editor的實例。但是被重用的renderer 或者item editor的實例不會再次發生creationComplete事件。作爲替代,你可以使用dataChange事件。Flex 會在每次data屬性發生變化時觸發dataChange事件。在Accessing the listData property(Flex2 help中)一節中的例子就使用了dataChange事件來更新在DataGrid控件的item renderer中的TextArea的內容。

轉:http://hi.baidu.com/woaidelphi/blog/item/1d1cb7667464ba2caa184c39.html

發佈了16 篇原創文章 · 獲贊 4 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章