[ActionScript 3.0] AS3.0 動態加載顯示內容

能夠將下列任何外部顯示資源加載到 ActionScript 3.0 應用程序中:html

  • 在 ActionScript 3.0 中創做的 SWF 文件 — 此文件能夠是 Sprite、MovieClip 或擴展 Sprite 的任何類。在 iOS 上的 AIR 應用程序中,只能加載不包含 ActionScript 字節代碼的 SWF 文件。這意味着能夠加載包含嵌入數據(如圖像和聲音)的 SWF 文件,但不能加載包含可執行代碼的 SWF 文件。ios

  • 圖像文件 — 包括 JPG、PNG 和 GIF 文件。安全

  • AVM1 SWF 文件 — 用 ActionScript 1.0 或 2.0 編寫的 SWF 文件。(在移動 AIR 應用程序中不受支持)服務器

使用 Loader 類能夠加載這些資源。網絡

加載顯示對象

Loader 對象用於將 SWF 文件和圖形文件加載到應用程序中。Loader 類是 DisplayObjectContainer 類的子類。Loader 對象在其顯示列表中只能包含一個子顯示對象,該顯示對象表示它加載的 SWF 或圖形文件。以下面的代碼所示,在顯示列表中添加 Loader 對象時,還能夠在加載後將加載的子顯示對象添加到顯示列表中:app

var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
this.addChild(pictLdr);

 

加載 SWF 文件或圖像後,便可將加載的顯示對象移到另外一個顯示對象容器中,如本示例中的containerDisplayObjectContainer 對象:dom

import flash.display.*; 
import flash.net.URLRequest; 
import flash.events.Event; 
var container:Sprite = new Sprite(); 
addChild(container); 
var pictLdr:Loader = new Loader(); 
var pictURL:String = "banana.jpg" 
var pictURLReq:URLRequest = new URLRequest(pictURL); 
pictLdr.load(pictURLReq); 
pictLdr.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);  
function imgLoaded(event:Event):void 
{ 
    container.addChild(pictLdr.content);  
}

 

監視加載進度

文件開始加載後,就建立了 LoaderInfo 對象。LoaderInfo 對象用於提供加載進度、加載者和被加載者的 URL、媒體的字節總數及媒體的標稱高度和寬度等信息。LoaderInfo 對象還調度用於監視加載進度的事件。網站

下圖說明 LoaderInfo 對象的不一樣用途 — 用於 SWF 文件的主類的實例、用於 Loader 對象以及用於由 Loader 對象加載的對象:this

能夠將 LoaderInfo 對象做爲 Loader 對象和加載的顯示對象的屬性進行訪問。加載一開始,就能夠經過 Loader 對象的contentLoaderInfo屬性訪問 LoaderInfo 對象。加載完顯示對象後,也能夠經過顯示對象的loaderInfo屬性,將 LoaderInfo 對象做爲已加載顯示對象的屬性進行訪問。已加載顯示對象的loaderInfo屬性是指與 Loader 對象的contentLoaderInfo屬性相同的 LoaderInfo 對象。換句話說,LoaderInfo 對象是加載的對象與加載它的 Loader 對象之間(加載者和被加載者之間)的共享對象。url

要訪問加載的內容的屬性,須要在 LoaderInfo 對象中添加事件偵聽器,以下面的代碼所示:

import flash.display.Loader; 
import flash.display.Sprite; 
import flash.events.Event; 
 
var ldr:Loader = new Loader(); 
var urlReq:URLRequest = new URLRequest("Circle.swf"); 
ldr.load(urlReq); 
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded); 
addChild(ldr); 
 
function loaded(event:Event):void 
{ 
    var content:Sprite = event.target.content; 
    content.scaleX = 2; 
}

 

有關詳細信息,請參閱處理事件

指定加載上下文

經過 Loader 類的load()loadBytes()方法將外部文件加載到 Flash Player 或 AIR 中時,能夠選擇指定context參數。此參數是一個 LoaderContext 對象。

LoaderContext 類包括三個屬性,用於定義如何使用加載的內容的上下文:

  • checkPolicyFile:僅當加載圖像文件(不是 SWF 文件)時纔會使用此屬性。若是將此屬性設置爲true,Loader 將檢查策略文件的原始服務器(請參閱網站控制(策略文件))。只有內容的來源域不是包含 Loader 對象的 SWF 文件所在的域時才須要此屬性。若是服務器授予 Loader 域權限,Loader 域中 SWF 文件的 ActionScript 就能夠訪問加載圖像中的數據;換句話說,可使用BitmapData.draw()命令訪問加載的圖像中的數據。

    請注意,來自 Loader 對象所在域之外的其餘域的 SWF 文件能夠經過調用Security.allowDomain()來容許特定的域。

  • securityDomain:僅當加載 SWF 文件(不是圖像)時纔會使用此屬性。若是 SWF 文件所在的域與包含 Loader 對象的文件所在的域不一樣,則指定此屬性。指定此選項時,Flash Player 將檢查策略文件是否存在,若是存在,來自跨策略文件中容許的域的 SWF 文件能夠對加載的 SWF 內容執行跨腳本操做。能夠將flash.system.SecurityDomain.currentDomain指定爲此參數。

  • applicationDomain:僅當加載使用 ActionScript 3.0 編寫的 SWF 文件(不是圖像或使用 ActionScript 1.0 或 2.0 編寫的 SWF 文件)時纔會使用此屬性。加載文件時,經過將applicationDomain參數設置爲flash.system.ApplicationDomain.currentDomain,能夠指定將該文件包括在與 Loader 對象相同的應用程序域中。經過將加載的 SWF 文件放在同一個應用程序域中,能夠直接訪問它的類。若是要加載的 SWF 文件中包含嵌入的媒體,這會頗有幫助,您能夠經過其關聯的類名訪問嵌入的媒體。有關詳細信息,請參閱使用應用程序域

下面的示例在從另外一個域加載位圖時檢查策略文件:

var context:LoaderContext = new LoaderContext(); 
context.checkPolicyFile = true; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/photo11.jpg"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

 

下面的示例在從另外一個域加載 SWF 時檢查策略文件,以便將該文件與 Loader 對象放在同一個安全沙箱中。此外,該代碼還將加載的 SWF 文件中的類添加到與 Loader 對象的類相同的應用程序域中:

var context:LoaderContext = new LoaderContext(); 
context.securityDomain = SecurityDomain.currentDomain; 
context.applicationDomain = ApplicationDomain.currentDomain; 
var urlReq:URLRequest = new URLRequest("http://www.[your_domain_here].com/library.swf"); 
var ldr:Loader = new Loader(); 
ldr.load(urlReq, context);

 

有關詳細信息,請參閱用於 Adobe Flash Platform 的 ActionScript 3.0 參考中的 LoaderContext 類。

在 AIR for iOS 中加載 SWF 文件

在 iOS 設備上,對於在運行時加載和編譯代碼存在限制。因爲這些限制,將外部 SWF 文件加載到您的應用程序中勢必會有一些不一樣:

  • 全部包含 ActionScript 代碼的 SWF 文件都必須包括在應用程序包中。不能從外部源(如經過網絡)加載包含代碼的 SWF。在對應用程序進行打包時,對於 iOS 設備,應用程序包中全部 SWF 文件中的全部 ActionScript 代碼都將編譯成本機代碼。

  • 您不能加載 SWF 文件,而後卸載它再從新加載。若是這樣作,會發生錯誤。

  • 加載到內存中而後又卸載的行爲與在桌面平臺上這樣操做的結果相同。若是加載 SWF 文件而後卸載它,包含在該 SWF 中的全部可視資源都將從內存中卸載掉。不過,對所加載 SWF 中的 ActionScript 類的任何類引用將保留在內存中,能夠在 ActionScript 代碼中訪問這些類引用。

  • 加載的全部 SWF 文件必須與主 SWF 文件使用相同的應用程序域。這並不是默認行爲,所以對於每一個要加載的 SWF,您必須建立一個 LoaderContext 對象來指定主應用程序域,並將該 LoaderContext 對象傳遞給 Loader.load() 方法調用。若是要加載的 SWF 所處的應用程序域與主 SWF 應用程序域不一樣,便會發生錯誤。即便加載的 SWF 只包含可視資源而不包含 ActionScript 代碼,也是這樣。

    下例中的代碼將一個 SWF 從應用程序包中加載到主 SWF 應用程序域中:

var loader:Loader = new Loader(); 
var url:URLRequest = new URLRequest("swfs/SecondarySwf.swf"); 
var loaderContext:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain, null); 
loader.load(url, loaderContext);

 

 

對於只包含資源而不包含代碼的 SWF 文件,能夠從應用程序包加載,也能夠經過網絡加載。不管哪種狀況,都必須仍將 SWF 文件加載到主應用程序域中。

對於 AIR 3.6 以前的版本,在編譯過程期間,全部代碼都是從非主應用程序 SWF 中去除。只包含可視資源的 SWF 文件能夠包括在應用程序包中並在運行時加載,但對於包含代碼的 SWF 不是這樣。若是要加載的 SWF 包含 ActionScript 代碼,便會發生錯誤。該錯誤會致使應用程序中出現一個「未編譯的 ActionScript」錯誤對話框。

另請參見

在 iOS 上的 AIR 應用程序中打包並加載多個 SWF

使用 ProLoader 和 ProLoaderInfo 類

爲了幫助預加載運行時共享庫 (RSL),Flash Professional CS5.5 引入了 fl.display.ProLoader 和 fl.display.ProLoaderInfo 類。這些類會鏡像 flash.display.Loader 和 flash.display.LoaderInfo 類,但提供了更加一致的加載體驗。

特別是,ProLoader 可幫助您加載使用 Text Layout Framework (TLF) 執行 RSL 預加載的 SWF 文件。在運行時,預加載其餘 SWF 文件或 SWZ 文件(例如 TLF)的 SWF 文件須要僅供內部使用的 SWF 包裝文件。SWF 包裝文件會增長調用結構的複雜性,並可能產生沒必要要的行爲。ProLoader 能夠消除這種複雜關係,它能夠像加載普通 SWF 文件那樣加載這些文件。ProLoader 類使用的解決方法對於用戶來講是透明的,不須要在 ActionScript 中執行任何特殊處理。此外,ProLoader 還能夠正確加載普通 SWF 內容。

在 Flash Professional CS 5.5 和更高版本中,您能夠安全地將全部 Loader 類替換爲 ProLoader 類。而後,將您的應用程序導出到 Flash Player 10.2 或更高版本,以便 ProLoader 可以訪問所需的 ActionScript 功能。您也能夠在面向支持 ActionScript 3.0 的 Flash Player 早期版本的應用程序中使用 ProLoader。可是隻有在 Flash Player 10.2 或更高版本中才能充分利用 ProLoader 的強大功能。當您在 Flash Professional CS5.5 或更高版本中使用 TLF 時,請始終使用 ProLoader。在 Flash Professional 以外的環境中,不須要使用 ProLoader。

重要說明: 對於在 Flash Professional CS5.5 和更高版本中發佈的 SWF 文件,您能夠始終使用 fl.display.ProLoader 和 fl.display.ProLoaderInfo 類,而不要使用 flash.display.Loader 和 flash.display.LoaderInfo。

ProLoader 類解決的問題

ProLoader 類解決了此前 Loader 類沒法處理的問題。這些問題是在對 TLF 庫執行 RSL 預加載的過程當中產生的。具體來講,在使用 Loader 對象加載其餘 SWF 文件的 SWF 文件中會碰到這些問題。解決的問題包括:

  • 加載文件和被加載文件之間的腳本處理沒法按預期方式執行。ProLoader 類會自動將加載 SWF 文件設置爲被加載 SWF 文件的父項。所以,來自加載 SWF 文件的通訊會直接轉到被加載 SWF 文件。

  • SWF 應用程序必須主動管理加載過程。要進行主動管理,須要實現額外的事件,例如addedremovedaddedToStageremovedFromStage。若是您的應用程序是面向 Flash Player 10.2 或更高版本,則 ProLoader 可消除這些額外的工做。

更新代碼,使用 ProLoader 來替代 Loader

因爲 ProLoader 會鏡像 Loader 類,您能夠輕鬆地在代碼中切換這兩個類。下面的示例顯示瞭如何更新現有代碼以使用新類:

import flash.display.Loader; 
import flash.events.Event; 
var l:Loader = new Loader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}

 

可將此代碼更新爲使用 ProLoader,以下所示:

import fl.display.ProLoader; 
import flash.events.Event; 
var l:ProLoader = new ProLoader(); 
 
addChild(l); 
l.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete); 
l.load("my.swf"); 
function loadComplete(e:Event) { 
    trace('load complete!'); 
}
相關文章
相關標籤/搜索