Flex程序從本質(zhì)上講,就是使用了(由AS編寫的)Flex框架的Flash程序。
但在Flex程序中可以忽略timeline這個概念,所有的內(nèi)容都集于一幀。
事實上Flex程序中的根,是繼承flash.display.MovieClip的mx.managers.SystemManager。
SystemManager有兩幀。第一幀是預(yù)加載程序,第二幀是主程序。
因此,所有程序在真正開始運行前,需要經(jīng)過如下過程:
預(yù)初始(preinitialize)
程序在這個過程后,已經(jīng)被實例化,但還未創(chuàng)建任何內(nèi)容。
初始化(initialize)
程序在這個過程后,已創(chuàng)建好內(nèi)容,但還未完成布局。
創(chuàng)建完成(creationComplete)
程序在這個過程后,已完成包括布局在內(nèi)的所有創(chuàng)建。
在順利完成以上3個過程后,SystemManager廣播applicationComplete事件,意味著程序整裝待發(fā)了。
SystemManager還管理著所有顯示在前端的內(nèi)容。包括彈出窗,鼠標指針,工具提示等。
SystemManager有一個叫totelLevelSystemManager的屬性。當Flex程序是一個獨立程序時,該屬性指向SystemManager的實例,而當Flex程序是被加載到別的Flex程序時,該屬性指向加載者的SystemManager實例。
所有UIComponents都有一個systemManager的屬性,指向程序的SystemManager實例。
了解預(yù)加載器
預(yù)加載器由SystemManager在第一幀自動創(chuàng)建,當完成后發(fā)布complete事件,并進入第二幀,再由SystemManager刪除。
除了complete以外,還有如下事件:
progress:程序下載過程
rslError:運行期共享庫下載失敗
rslProgress:運行期共享庫下載過程
rslComplete:運行期共享庫下載完成
initProgress:程序初始化過程
initComplete:程序初始化完成
在Flex程序中加載另一個Flex程序
被加載的Flex程序,在加載完畢后,自身內(nèi)部會經(jīng)歷上述3個過程。最終,主程序才能對該程序進行有效的訪問。
private function initHandler(event:Event):void {
event.target.content.addEventListener(FlexEvent.APPLICATION_COMPLETE, applicationCompleteHandler);
}
private function applicationCompleteHandler(event:Event):void {
event.target.application.setBackground(0xFFFF00);
}
]]>
</mx:Script>
<mx:SWFLoader source="B.swf" init="initHandler(event)" />
</mx:Application>
了解程序作用域
當程序中牽涉到加載外部.swf程序時,了解程序作用域的概念是非常重要的。
首先要了解所有的Flex/Flash程序都是由一系列類組合而成。這一系列類都維持在一個程序作用域中。當僅有一個程序在運行時,程序作用域的概念只是一個形式,因為不可能發(fā)生作用域沖突的事情。當加載額外的.swf程序后,情況就不一樣了,此時,可能會發(fā)生3種情況:
被加載的.swf在現(xiàn)有作用域的子作用域中運行
這種情況下,被加載.swf可以使用父作用域中的所有類,而本身作用域中和父作用域中沖突的類,將被忽視。
這樣子有3個好處:
減少內(nèi)存的占用。
單態(tài)管理者(Singleton manager classes)可以訪問父級程序,也可以訪問子級程序。
從技術(shù)角度講,在編譯子級程序時,可以不用把重復(fù)的類編譯進去,從而減少文件大小
但有時不能忽視子作用域的類。比如碰到類名雖然沖突,但功能卻不相同時。
被加載的.swf在一個新的完全獨立的作用域中運行
這種情況下,被加載.swf在一個不受任何約束的作用域中運行。雖然不會發(fā)生什么沖突,但這樣會加大內(nèi)存的占用。
被加載的.swf在現(xiàn)有作用域中運行
這種情況下,被加載.swf在現(xiàn)有的作用域中運行,被看作現(xiàn)有內(nèi)容的一部分。常常用于運行期共享庫。
實現(xiàn)上述3種情況的代碼如下:
//------------------------------------------------------------
// 被加載的.swf在現(xiàn)有作用域的子作用域中運行
//------------------------------------------------------------
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
var request:URLRequest = new URLRequest("RuntimeLoadingExample.swf");
var loader:Loader = new Loader();
loader.load(request, context);
// 等同于
var request:URLRequest = new URLRequest("RuntimeLoadingExample.swf");
var loader:Loader = new Loader();
loader.load(request);
//------------------------------------------------------------
// 被加載的.swf在一個新的完全獨立的作用域中運行
//------------------------------------------------------------
var context:LoaderContext = new LoaderContext();
context.applicationDomain = new ApplicationDomain();
var request:URLRequest = new URLRequest("RuntimeLoadingExample.swf");
var loader:Loader = new Loader();
loader.load(request, context);
//------------------------------------------------------------
// 被加載的.swf在現(xiàn)有作用域中運行
//------------------------------------------------------------
var context:LoaderContext = new LoaderContext();
context.applicationDomain = ApplicationDomain.currentDomain;
var request:URLRequest = new URLRequest("RuntimeLoadingExample.swf");
var loader:Loader = new Loader();
loader.load(request, context);
loadContext
ApplicationDomain
Flash Player和Flex框架的不同
Flash Player是Flash/Flex程序的運行環(huán)境。它用來運行.swf文件,完成加載圖片,繪制圖像,請求HTTP等之類的操作。Flash/Flex程序只能做Flash Player能夠做的事情。
Flex程序就是Flash程序,F(xiàn)lash不能做的事情,F(xiàn)lex一樣不能做。所以程序包含的只不過是具體指令,而Flash Player則是運行指令。Flash程序和Flex程序在內(nèi)容上沒有不同,只是在創(chuàng)建內(nèi)容時不同。
Flex的編譯器可以編譯MXML和AS。由AS和MXML編寫的Flex框架抽象出一個更高級的層面。這些都能在Flash Player中運行。
改善的是開發(fā)速度。
負面影響則是增加了.swf的大小。因為Flex框架是要被具體編譯到.swf里面的,而不像Flash Player API已經(jīng)集成在Flash Player內(nèi)部了。