Flex3中Application裡的屬性application這個屬性在Flex4中被拿掉了,改由 FlexGlobalse這各類管理,由FlexGlobalse的topLevelApplication屬性代替原本的appliction,topLevelApplication這是一個靜態的屬性。
什麼是topLevelApplication?
在的ApplicationDomain中運行的第一個應用程序是頂層應用程序。在頂層應用程序的構造函數中,將此屬性設置為對頂層應用程序的引用。每個 ApplicationDomain中都有其自己的topLevelApplication,這個topLevelApplication通常就是一支SWF,在Flex中這支SWF通常會是一個Application的實體,在一個ApplicationDomain中可能會有多個SWF存在,但只會有一個負責管理所有應用程式的最上層Application,這個管理者就是topLevelApplication。
adobe技術手冊中的圖示如下:
範例:在一SWF中利用Loader讀取另一支SWF,在loader()第二個參數使用預設null。
請參考LoaderI與LoaderContext
- loader()第二參數為null時,將使用Loader所在的Application的ApplicationDomain。
<?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/mx" minWidth="1280" minHeight="780"
applicationComplete="application1_applicationCompleteHandler(event)"
pageTitle="Hero_Test"
>
<fx:Script>
<![CDATA[
import mx.core.FlexGlobals;
import mx.core.UIComponent;
import mx.events.FlexEvent;
import mx.managers.SystemManager;
private var _loader:Loader;
private var _request:URLRequest;
private var _systemManager:SystemManager;
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
initLoader();
deployLoader();
startLoader();
btn.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
}
private function initLoader():void
{
_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE , onLoaderComplete);
_request = new URLRequest('./swf/ByLoaderSWF.swf');
}
private function deployLoader():void
{
uic.addChild(_loader);
this.box.addElement(uic);
}
private function startLoader():void
{
_loader.load(_request);
}
private function onLoaderComplete(e:Event):void
{
_systemManager = _loader.content as SystemManager;
changedColorBtn.addEventListener(MouseEvent.MOUSE_DOWN , onChangeColor);
uic.width = _loader.content.width;
uic.height= _loader.content.height;
}
private function onChangeColor(e:MouseEvent):void
{
var color:uint = Math.round(Math.random()* 0xFFFFFF);
_systemManager.application['setByLoaderSWFbackgroud'](color);
info.text = color.toString();
}
private function onDown(e:MouseEvent):void
{
var o:Object = FlexGlobals.topLevelApplication;
info.text ="";
info.text = "this = " + this + '\n\n';
info.text += 'topLevelApplication = ' + o.toString()+'\n\n';
info.text += 'systemManager = ' + this.systemManager + '\n\n';
}
]]>
</fx:Script>
<s:HGroup id="box">
<s:VGroup>
<s:Panel title="Hero_Test">
<s:TextArea id="info" editable="false" width="420"/>
</s:Panel>
<s:Label text="print Hero_Test資訊"/>
<s:Button id="btn" label="print"/>
<s:Button id="changedColorBtn" label="changeColor"/>
</s:VGroup>
<mx:UIComponent id="uic"/>
</s:HGroup>
</s:Application>
程式碼ByLoaderSWF.mxml:
<?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/mx" minWidth="600" minHeight="200"
applicationComplete="application1_applicationCompleteHandler(event)"
pageTitle="ByLoaderSWF"
backgroundColor="0xA1FF8F"
>
<s:layout>
<s:BasicLayout/>
</s:layout>
<fx:Script>
<![CDATA[
import mx.controls.ProgressBar;
import mx.core.FlexGlobals;
import mx.events.FlexEvent;
import mx.managers.SystemManager;
import mx.preloaders.DownloadProgressBar;
protected function application1_applicationCompleteHandler(event:FlexEvent):void
{
Security.allowDomain("*");
btn.addEventListener(MouseEvent.MOUSE_DOWN , onDown);
}
private function onDown(e:MouseEvent):void
{
var _topLevelApplication:Object = FlexGlobals.topLevelApplication;
info.text ="";
info.text = "this = " + this + '\n\n';
info.text += 'topLevelApplication = ' + _topLevelApplication.toString()+'\n\n';
info.text += 'systemManager = ' + this.systemManager + '\n\n';
}
public function setByLoaderSWFbackgroud(color:uint):void
{
this.setStyle("backgroundColor",color);
}
]]>
</fx:Script>
<s:VGroup>
<s:Panel title="ByLoaderSWF資訊看板">
<s:TextArea id="info" editable="false" width="450"/>
</s:Panel>
<s:VGroup>
<s:Label text="Print ByLoaderSWF資訊"/>
<s:Button id="btn" label="print"/>
</s:VGroup>
</s:VGroup>
</s:Application>
將這兩支mxml編譯成SWF,並將發佈的的資料放置Web Server中運行。
- 注意,Loader在load SWF時,無法在flashBuilder中直接執行運作,因為Loader SWF不可在本機上執行,這是FlashPlayer的安全機制,將其放置Web Server中運行即可。
我們可以看到ByLoaderSWF的topLevelApplication是指向Hero_Test。
而我們可以在Hero_Test中呼叫ByLoaderSWF的public function 。
呼叫ByLoaderSWF的setByLoaderSWFbackgroud(color:uint)方式如下:
//在Loder的contentLoaderInfo讀取完畢發出Complete時將Loader的content轉成SystemManager。
private var _systemManager:SystemManager;
private function onLoaderComplete(e:Event):void
{
_systemManager = _loader.content as SystemManager;
changedColorBtn.addEventListener(MouseEvent.MOUSE_DOWN , onChangeColor);
}
//在Button被按下後呼叫,利用_systemManager來呼叫setByLoaderSWFbackgroud(color:uint)
private function onChangeColor(e:MouseEvent):void
{
var color:uint = Math.round(Math.random()* 0xFFFFFF);
_systemManager.application['setByLoaderSWFbackgroud'](color);
info.text = color.toString();
}
什麼是SystemManager?
- SystemManager是應用程式的根(root)。
- SystemManager是MovieClip的子類,有兩個影格。
- SystemManager在第一個影格是預載器,在此會載入。
- SystemManager在第二個影格會開始建立主要應用程式的實體。
- SystemManager有個application屬性,會指向Application的實體。
- application這個屬性在第二影格建立屬性前都會是null,也就是說SystemManager是一支應用程式中最先建立的然後才是建立Flex中主要應用程式的類別(如Application)。
systemManager中有一個屬性application其實就是Application的instance,而在這裡_systemManager中其實就是ByLoaderSWF的SystemManager。
關於this對象、SystemManager對象、SystemManager.application在ByLoaderSWF單獨執行下的追蹤結果。
沒有留言:
張貼留言