ApplicationDomain 類別的目的是用於儲存 ActionScript 3.0 的定義表格。SWF 檔中的所有程式碼都定義為存在應用程式網域中。您可以使用應用程式網域,分割位於相同安全性網域中的類別。這麼做能允許相同的類別具有多項定義,並讓子系重新使用父輩定義。
您可以在使用 Loader 類別 API 載入以 ActionScript 3.0 撰寫的外部 SWF 檔時,使用應用程式網域 (請注意,當您載入以 ActionScript 1.0 或 ActionScript 2.0 撰寫的影像或 SWF 檔時,將無法使用應用程式網域)。所有包含在載入類別中的 ActionScript 3.0 定義都會儲存在應用程式網域中。載入 SWF 檔時,您可以將 LoaderContext 物件的
applicationDomain
參數設定為
ApplicationDomain.currentDomain
,指定將該檔案包含在與 Loader 物件檔案相同的應用程式網域中。藉由將載入的 SWF 檔置於相同的應用程式網域中,便可以直接存取其類別。如果您要載入包含內嵌媒體 (透過媒體相關類別名稱進行存取) 的 SWF 檔,或是要存取所載入 SWF 檔的方法,這就十分有用。
下列範例假設它可以存取不同的 Greeter.swf 檔案,該檔案定義公用方法 welcome():
package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.*;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
public class ApplicationDomainExample extends Sprite
{
private var ldr:Loader;
public function ApplicationDomainExample()
{
ldr = new Loader();
var req:URLRequest = new URLRequest("Greeter.swf");
var ldrContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
ldr.load(req, ldrContext);
}
private function completeHandler(event:Event):void
{
var myGreeter:Class = ApplicationDomain.currentDomain.getDefinition("Greeter") as Class;
var myGreeter:Greeter = Greeter(event.target.content);
var message:String = myGreeter.welcome("Tommy");
trace(message); // Hello, Tommy
}
}
}
另請參閱
適用於 Adobe Flash Platform 的 ActionScript 3.0 參考
中的
ApplicationDomain
類別範例。
當您處理應用程式網域時,其它要注意的事項包括:
-
SWF 檔中的所有程式碼都定義為存在應用程式網域中。「目前的網域」是指您的主應用程式在其中執行的網域。「系統網域」則包含所有的應用程式網域,其中包括目前的網域,也就是包含了所有的 Flash Player 類別。
-
所有的應用程式網域,除了系統網域之外,都具有相關的父網域。您的主應用程式之應用程式網域的父網域,就是系統網域。只有在其父輩尚未定義載入的類別時,才會定義這些類別。因此,您不能以較新的定義覆寫載入類別的定義。
下圖顯示在單一網域 domain1.com 中,從各種不同 SWF 檔載入內容的應用程式。根據所載入的內容而定,可能會用到不同的應用程式網域。下方的文字說明在應用程式中用來為每一個 SWF 檔設定適當應用程式網域的邏輯。
主應用程式檔案為 application1.swf,它包含會從其它 SWF 檔載入內容的 Loader 物件。在此案例中,目前的網域是「應用程式網域 1」。用法 A、用法 B 和用法 C 各說明不同的技巧,可用來在應用程式中為每一個 SWF 檔設定適當的應用程式網域。
-
用法 A
-
藉由建立系統網域的子系,分割子 SWF 檔。在圖中,「應用程式網域 2」是建立做為系統網域的子網域,application2.swf 檔會載入至「應用程式網域 2」中,而其類別定義就會從 application1.swf 所定義的類別中分割出來。
此技巧的其中一項用法,就是讓舊的應用程式以動態方式載入較新版的相同應用程式,而不造成衝突。沒有發生衝突的原因,是因為雖然使用了相同的類別名稱,但是類別都已經分割而位於不同的應用程式網域中。
下列程式碼會建立系統網域子系的應用程式網域,並開始使用該應用程式網域載入 SWF:
var appDomainA:ApplicationDomain = new ApplicationDomain();
var contextA:LoaderContext = new LoaderContext(false, appDomainA);
var loaderA:Loader = new Loader();
loaderA.load(new URLRequest("application2.swf"), contextA);
-
用法 B:
-
將新的類別定義新增至目前的類別定義。module1.swf 的應用程式網域設定為目前的網域 (應用程式網域 1),這可讓您在應用程式目前的類別定義集中,加入新的類別定義。這可以用來做為主應用程式的執行階段共享元件庫。所載入的 SWF 會視為執行階段共享元件庫 (RSL)。您可以使用這項技巧,在應用程式開始之前,預先載入器載入 RSL。
下列程式碼會載入 SWF,並將其應用程式網域設定為目前的網域:
var appDomainB:ApplicationDomain = ApplicationDomain.currentDomain;
var contextB:LoaderContext = new LoaderContext(false, appDomainB);
var loaderB:Loader = new Loader();
loaderB.load(new URLRequest("module1.swf"), contextB);
-
用法 C:
-
透過建立目前網域的新子網域,使用父項目的類別定義。module3.swf 的應用程式網域是目前網域的子網域,這個子網域會使用父輩所有類別的版本。此技巧的其中一項用法,是可以做為具有多重螢幕之多樣化網頁應用程式 (Rich Internet Application,RIA) 的模組,此模組會載入為主應用程式的子系,並使用主應用程式的類型。如果您能確保所有類別都一定會升級以與舊版相容,而且載入內容的應用程式一定會比它所載入的內容更新,則子系將會使用父輩版本。如果您確定不會繼續參考子 SWF,則具有新的應用程式網域也可讓您取消載入所有的類別定義,以便進行記憶體回收。
這項技巧可讓載入模組共享載入器的 Singleton 物件和靜態類別成員。
下列程式碼會建立目前網域的新子網域,並使用該應用程式網域開始載入 SWF:
var appDomainC:ApplicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
var contextC:LoaderContext = new LoaderContext(false, appDomainC);
var loaderC:Loader = new Loader();
loaderC.load(new URLRequest("module3.swf"), contextC);