Loader與URLLoader,SWFLoader

 

(1) Loader        
Loader 類可用於加載 SWF 文件或圖像(JPG、PNG 或 GIF)文件。 使用 load() 方法來啓動加載。 被加載的顯示對象將做爲 Loader 對象的子級添加。        
(2)URLLoader        
URLLoader 類以文本、二進制數據或 URL 編碼變量的形式從 URL 下載數據。 在下載文本文件、XML 或其它用於動態數據驅動應用程序的信息時,它頗有用。URLLoader 對象會先從 URL 中下載全部數據,而後纔將數據用於 ActionScript。 它會發出有關下載進度的通知,經過 bytesLoaded 和bytesTotal 屬性以及已調度的事件,能夠監視下載進度。在加載很是大的視頻文件(如 FLV 的視頻文件)時,可能會出現內存不足錯誤。
 
區別:一個用來加載可顯示數據,一個用來加載非顯示數據由於loader是繼承與容器類的,因此首先它是個容器,而URLLoader 是繼承與EventDispatcher,它不是容器URLLoader 類以文本、二進制數據或 URL 編碼變量的形式從 URL 下載數據,在加載很是大的視頻文件(如 FLV 的視頻文件)時,可能會出現內存不足錯誤,返回的數據在data屬性裏面而loader多加載圖片,swf等可視化對象,加載後做爲惟一的子對象顯示在列表上。

應用範圍 
Loader: 多用於swf,圖片(jpg,png,gif) 
URLLoader: 多用於文本文件(xml,php,jsp…)
使用方法 
[java]  view plain copy
 
  1. //Loader:  
  2. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);   
  3. private function loadComplete(event:Event)  
  4. {   
  5.     trace("done");  
  6.     addChild(loader);  
  7. }  
  8.   
  9. //URLLoader:  
  10. xmlLoader.dataFormat=URLLoaderDataFormat.TEXT;   
  11. xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded);   
  12. private function xmlLoaded(event:Event) {   
  13.     try {  
  14.         myXML = XML(event.target.data);area.text=myXML;  
  15.     }catch (e:TypeError)   
  16.     {  
  17.         area.text="Load faild:\n"+e.message;  
  18.     }   
  19. }  
Loader
在使用Loader來加載數據時,添加偵聽事件時,注意必定要給Loader的 contentLoaderInfo屬性增長事件,而不是給Loader對象增長事件。
[java]  view plain copy
 
  1. var loader:Loader = new Loader();  
  2. loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);  
  3. loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);  
  4. loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);  
 
(3)可使用SWFLoader和Loader兩個類來加載子應用程序,多數狀況下咱們使用SWFLoader。它是Loader的一個包裝類,提供了不少附加功能,使加載子應用程序更簡單。
SWFLoader有以下特徵:
支持flex的樣式和特效;而Loader類卻不支持任何固有的樣式和特效。
方便管理加載進度;若是使用Loader則首先要獲取LoaderInfo引用。
 
是一個UIComponent組件。SWFLoader它本身管理了全部子顯示對象,不須要添加多餘的代碼。
自動縮放顯示內容的大小
 
能夠加載Application之外的實現類,若是檢測到不是一個Application,會自動進行處理。
能夠處理不一樣的版本。Loader不支持加載不一樣的編譯版本
 
當使用Loader加載不是受信任區域的swf時,必須提供一個遮罩來從新定位,不然它會顯示在屏幕外面:
代碼  
[java]  view plain copy
 
  1. import flash.display.*;    
  2. import flash.net.URLRequest;    
  3. var rect:Shape = new Shape();    
  4. rect.graphics.beginFill(0xFFFFFF);    
  5. rect.graphics.drawRect(0, 0, 100, 100);    
  6. addChild(rect);    
  7. var ldr:Loader = new Loader();    
  8. ldr.mask = rect;    
  9. var url:String = "http://www.unknown.example.com/content.swf";    
  10. var urlReq:URLRequest = new URLRequest(url);    
  11. ldr.load(urlReq);    
  12. addChild(ldr);   
SWFLoader加載外部swf是一個很好的方法,在進行Flex遊戲開發的時候,咱們一般會須要不少Flash提供的遊戲角色,這些角色能夠每一個都是一個單獨的swf,也能夠是存在於一個swf文件中的各個元件。兩種方法各有優劣:
1. 單獨的swf,每一個角色獨立性很強,能夠在須要的時候才加載。將來修改角色也不會影響到其它角色。可是會有不少的swf須要管理。
2. 每一個角色是一個元件,存在於一個swf中,這種方法比較容易管理資源,比較乾淨。可是修改一個角色都須要從新編譯swf,可能會誤操做影響其它的元件。並且一次加載全部角色,可能會加載許多沒必要要的元件,浪費帶寬。


兩種方法怎麼選擇,根據項目讀者根據如下幾個問題考慮:
1. 你的全部元件相互之間是否又不少公用元件?若是是的話,能夠考慮放到一個swf中,由於這樣會下降全部元件的文件量。
2. 你的全部元件是否都繼承同一些類,實現同一些接口,調用同一些類?若是是的話,能夠考慮放到一個swf中,這樣比較容易管理類包,並且下降swf的文件量,由於共有的類只編譯一次。
3. 你的全部元件是否徹底獨立,沒有任何關係?若是是的話,你能夠考慮每一個角色獨立的swf。
具體實現代碼以下:
[java]  view plain copy
 
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"   
  3.                xmlns:s="library://ns.adobe.com/flex/spark"   
  4.                xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600"  
  5.                creationComplete="init()"  
  6.                >  
  7.     <fx:Declarations>  
  8.         <!-- Place non-visual elements (e.g., services, value objects) here -->  
  9.     </fx:Declarations>  
  10.     <fx:Script>  
  11.         <![CDATA[  
  12.             import mx.controls.SWFLoader;  
  13.             import mx.core.UIComponent;  
  14.    
  15.             private var swfLoader:SWFLoader = new SWFLoader();  
  16.             private function init():void{  
  17.                 swfLoader.addEventListener(Event.COMPLETE,swfLoadComplete);  
  18.                 swfLoader.load("assets/fishmomo.swf");  
  19.             }  
  20.             private function swfLoadComplete(e:Event):void{  
  21.                 /** 
  22.                  * 將整個swf都加載到flex舞臺上 
  23.                  * 此方法將每一個flex要用的資源作成單獨的swf,須要時才加載進來 
  24.                  */   
  25.                 addElement(swfLoader);  
  26.                 var swf:MovieClip = swfLoader.content as MovieClip;  
  27.                 //fish 是 swf主舞臺上的一個魚對象,屬性命名爲fish  
  28.                 //調用舞臺上fish元件的say方法  
  29.                 swf.fish.say("Load a swf");  
  30.    
  31.                 /** 
  32.                  * 此方法能夠把全部的flex要用的資源放到一個swf中 
  33.                  * 把須要在flex中使用的元件連接到一個類,並將此元件拖到flash舞臺 
  34.                  * 經過類名,隨意顯示其中一個元件到flex舞臺 
  35.                  */   
  36.                 var FishSymbol:Object = swfLoader.content.loaderInfo.applicationDomain.getDefinition("Fish");  
  37.                 var f:MovieClip = new FishSymbol() as MovieClip;  
  38.                 //調用元件的say方法  
  39.                 f.say("Load a symbol within a swf");  
  40.                 var ui:UIComponent = new UIComponent();  
  41.                 ui.addChild(f);  
  42.                 addElement(ui);  
  43.             }  
  44.         ]]>  
  45.     </fx:Script>  
  46. </s:Application>  

致使內存泄露的一些狀況:

事件監聽:
對父級對象加了監聽函數,會形成內存泄露,例:
override protected function mouseDownHandler(…):void {
systemManager.addEventListener(「mouseUp」, mouseUpHandler);
……
}
解決:
在銷燬對象的時候,remove掉這些監聽,雖然弱引用也能夠避免這些問題,但本身掌控感受更好。
但如下幾種狀況不會形成內存泄露:
弱引用:someObject.addEventListener(MouseClick.CLICK, handlerFunction, false, 0, true);
對本身的引用:this.addEventListener(MouseClick.CLICK, handlerFunction);
子對象的引用:
private var childObject:UIComponent = new UIComponent;
addChild(childObject);
childObject.addEventListener(MouseEvent.CLICK, clickHandler);
總之…有addEventListener,就removeEventListener一下吧,要爲本身作的事負責~哈哈

清除引用
remove掉子對象後並不會刪除該對象,他還保留在內存中,應該將引用設置爲null
removeChildren(obj);
obj = null;

靜態成員
Class (或MXML)中有:
public static var _eventService : MyService=new MyService();
解決:在dispose時,須要設置:
_eventService =null;

module (未解決)
moduleLoader unloadModule後
ModuleInfo 並不會被GC.
Garbage Collection in a MultiCore Modular Pipes Application
這篇文章介紹了一種GC策略,感受對於ModuleInfo 的GC無效。
(何嘗試、未遇到)

CSS樣式
module 中若是使用了shell的CSS定義或是<mx:Style> 這樣的定義,那麼這個module將不能GC.
彈出的窗口應該是一樣的結果.
解決方法,使用動態CSS文件
module init中
StyleManager.loadStyleDeclarations(「css/myStyle.swf」);
module dispose中
StyleManager.unloadStyleDeclarations(「css/myStyle.swf」);

TextInput/Textarea(未解決)
若是module中有window使用了TextInput/Textarea控件,不點擊沒有問題,只要點上去,那麼很遺憾了,module和所在窗體將不能被GC.
這個BUG很是嚴重,目前尚未解決方法。
memory leak when using TextInput and TextArea when click the keyboard 這裏面附加的解決方法無效。
經過profiler分析,應該和Focusmanager有關,只有一點擊就不會釋放。

CursorManager.setCursor
使用了
cursorID = CursorManager.setCursor(iconClosed);
dispose時要
CursorManager.removeCursor(cursorID);

Bitmap
若是使用Bitmap,結束時須要調用其dispose方法,不然內存消耗巨大。
另外,BitmapData是能夠共享使用的,多個Bitmap可使用同一BitmapData,節省很多內存。
var bmp:Bitmap =new Bitmap();
……..
if (bmp.bitmapData!=null) {
bmp.bitmapData.dispose();
}
Image
包含了Image對象時,在removeChildren時會形成不能釋放(測試屢次,結果不一,建議仍是作以下處理)。
解決:
img.source = null;
this.removeChild(img);
img = null;

Loader、SWFLoader、聲音、視頻、Effect等…
若是是加載SWF文件,先中止播放。
中止聲音的播放
中止正在播放的影片剪輯(Movieclip)
關閉任何鏈接的網絡對象,例如Loader正在加載,要先close。
取消對攝像頭或者麥克風的引用
取消事件監聽器
中止任何正在運行的定時器,clearInterval()
中止任何Timer對象,timer.stop()
中止正在播放的效果(Effect)
其餘

binding也疑似有memory leak 問題。
引用以及內存泄露相關博文和資料:
http://blogs.adobe.com/aharui/2007/03/garbage_collection_and_memory.html
http://www.craftymind.com/2008/04/09/kick-starting-the-garbage-collector-in-actionscript-3-with-air/
http://www.cnblogs.com/janyou/archive/2008/11/25/1340753.html
http://www.dreamingwell.com/articles/archives/2008/05/understanding_m.php
總結:因爲以前Flash一直是在網頁上使用,通常網頁都是看完就關掉的,估計Adobe在內存回收這塊也沒有下太大的功夫,
如今AIR的出現使得內存管理也至關重要了,而且,AIR自己對內存的消耗就至關大,一個沒有任何內容的初始建立的AIR程序,就得佔掉10-20M+的內存…AIR還需改善.

Modules

爲何要模塊化;模塊化提供了分離應用程序代碼到不一樣的swf文件上以便減小下載時間和文件大小。
使用Modules的好處是:
1. 主應用程序開始時不需立刻下載modules。應用程序會根據需求載入和卸載modules。
2. 因爲每一個modules獨立於其餘應用程序modules,當須要改變一個modules時,你只須要重編譯這個modules而不是整個應用程序。模塊化可建立模塊化應用程序是提升Flex框架性能的重要方面,提供更多能力控制下載時間和文件大小,使用modules,你能夠根據哪些可被獨立載入,哪些可被其餘程序使用而分離應用程序代碼。
 
優勢是合理分割了主Application,模塊化開發。更小的SWF文件體積,配合RSL和延遲加載策略,大大減小用戶等待時間。
缺點就是容易引發內存泄露。

RSL

  RSL(Runtime Shared Library),即運行時加載庫。當前L主要有3個級別的RSL,一個是Standard RSL(即一個網站內共享),一個是Cross-domain RSL(跨域共享),最後一個也是最關鍵的是Framework RSL(Flex框架共享)。
  功能說明
  Flex Builder在默認狀況下,編譯的每一個程序都是獨立的。每一個程序都包含了所需類的一個副本,例如:在多個程序中都用到了VBox這個控件,那麼每一個程序都要獨立的擁有一個VBox類。由此形成了程序代碼的重複,使得代碼量增大不少。而RSL正是解決此問題的一種方法,它能夠把共享代碼提取出來,而後在相同域的程序之間進行共享。這些共享代碼不會再編譯進程序,而是放在單獨的庫中,供運行時加載。另外,RSL也能夠在客戶端進行緩存,所以不須要在每次使用程序時重複下載。
 
RSL(Runtime shared libraries)即動態連接庫,在程序運行時由FlashPlayer動態加載。靜態連接庫是SWC文件,經過編譯器的library-path和include-libraries
編譯進應用程序。採用靜態連接的應用程序SWF會產生比較大的文件以及更長的下載時間。使用RSL的應用程序載入時間短且文件比較小,並且提升了內存使用效率,只是
在開始須要花點時間下載RSL。RSL的強大致如今多個應用程序共享公共代碼時,由於RSL只須要被下載一次,多個應用程序動態連接到相同的RSL,訪問其中已經緩存在客
戶端的資源。
使用RSL:
(1).在項目文件夾中點右建,選擇"properties"-"Flex Build Path"-"Library Path"
(2).該選項卡上咱們看到"FrameWork linkage",默認是"Merged into cdoe"(FLEX4默認是RSL)
(3).點開下拉,選擇"runtime shared library(RSL)"
(4).針對自定義的SWC,修改其link type爲RSL,選擇None,同時勾上Automatically extract swf to deployment path(自動將SWF提取到部署路徑)。若是想對不一樣域的RSL共享,則選擇Digests(摘要),同時指定其Policy file url(策略文件)。具體可參考FLEX SDK中的SWC文件處理方式。
(5).點擊OK

SWC

SWC 文件是相似 zip 的文件。靜態連接庫是SWC文件,經過編譯器的library-path和include-libraries編譯進應用程序。新建Flex Library Object或使用compc命令能夠製做SWC。

E4X

E4X是在ECMA-357標準中定義的,併成爲AS3的一部分。優勢是提供更簡明和可讀性強的語法從XML中查找和提取數據。

profile工具

能夠很方便地觀察對象的建立和銷燬,幫助檢查內存泄露問題。

FlexUnit

FlexUnit - Flex單元測試框架 

其餘

一、flex生成出來的文件都是很大,請問你用什麼辦法進行縮小呢?
(1)RSL
(2)Module
(3)外部加載資源

二、作一個flex項目,你認爲成功的要素在哪呢?
(1)數據和需求等傳統軟件項目的成功要素
(2)模塊化開發,MVC框架
(3)swf文件減肥,運行效率,內存泄露問題,前臺優化
(4)開源組件的使用

三、flex 前端的性能優化
(1)、避免容器的多級嵌套,減小相對尺寸、相對定位的使用。
(2)、儘可能使用輕量級的容器
(3)、避免使用大致積的組件,好比DataGrid、AdvancedDataGrid
(4)、處理數據時多用分頁的方式
(5)、少使用setStyle
(6)、使用延遲實例化加載子組件

4.Embed綁定圖片有什麼缺點?
答:直接編譯到swf文件中,形成其體積過大。並且因爲嵌入代碼中,維護不便。

五、flex裏調用JS措施?
答:直接在AS中利用ExternalInterface.call()來調用JS措施。如:
[java]  view plain copy
 
  1. import flash.external.ExternalInterface ;  
  2. ExternalInterface.call("JSFunction");  
  3. ExternalInterface.call("JSFunctionWithParameters","myParameter");  
  4. var result:String=ExternalInterface.call("JSFunctionWithReturn");  

六、用JavaScript調用ActionScript函數
答:利用ExternalInterface.addCallback在JavaScript裏設置對Flex的回調措施而且在JavaScript裏調用ActionScript措施。
[java]  view plain copy
 
  1. AS:  
  2. ExternalInterface.addCallback("function1",callback1);  
  3. privatefunctioncallback1():void  
  4. {  
  5. Alert.show("callback1executed");  
  6. }  
  7. JS:  
  8. container[swf].function1();  

六、FileReference
答:
[java]  view plain copy
 
  1. browse(typeFilter:Array = null):Boolean//揭示一個文件博覽對話框,讓用戶抉擇要上載的文件。  
  2. cancel():void//廢止正在對該 FileReference 對象厲行的任何上載或下載壟斷。  
  3. download(request:URLRequest, defaultFileName:String = null):void//敞開對話框,以批准用戶從長途服務器下載文件.  
  4. upload(request:URLRequest, uploadDataFieldName:String = "Filedata", testUpload:Boolean = false):void//開始將用戶抉擇的文件上載到長途服務器。  

七、flash與flex是如何調停開發的?
答:這個問題可以這麼來會意,萬一是確乎必需用到FLEX SDK的利用,那咱們就可以發生一個flex工程,翔實必需flash作UI的時候,輸出成swc做爲flex的skin,萬一說並沒有需要flex sdk,只是爲了編碼得體而抉擇flex的話,那咱們凡是發生一個as工程,讓flex做爲flash的編碼器。

八、請說下事件裏的currentTarget 和 target的區別?
答:在事件流的過程當中,目標階段肯定的目標對象由Event中的target屬性來記錄,
冒泡階段移動的遊標則由currentTarget來記錄。事件對象冒泡過程當中每往上移動一級,就會克隆出一個僅與前副本currentTarget不一樣的新副本。

九、warning: unable to bind to property 」 on class ‘Object’ (class is not an IEventDispatcher) 在使用ItemRender時,常常會出現這種警告?
答:ArrayCollection的子元素是沒法做爲數據源綁定的。能夠聲明中間變量,在override set data時將ArrayCollection的子元素傳入,
而後再將中間變量做爲新的綁定源便可。

十、經常使用的幾個切換數據的組件好比: TabNavigator等都有屬性 creationPolicy 你知道這種策略的使用方式是什麼嘛?以及優,缺點呢?
答:延遲實例化。優勢是能夠更快地加載組件,缺點是首次訪問其餘組件時,因爲須要從新加載此組件,可能會有必定的延遲。

十一、請試寫一個自定義的驗證組件
答:
[java]  view plain copy
 
  1. package myCompenent  
  2. {  
  3.     import mx.validators.Validator;//引用Validator類  
  4.     import mx.validators.ValidationResult;//引用ValidationResult類  
  5.     public class myValidators extends Validator  
  6.     {  
  7.         public function myValidators()//構造函數  
  8.         {  
  9.             super();  
  10.         }  
  11.         private var results:Array;//定義一個數組,用以存儲錯誤  
  12.         //重寫驗證函數  
  13.         override protected function doValidation(value:Object):Array  
  14.         {  
  15.             var s:String = value as String;  
  16.             results = [];//清空數組  
  17.             results = super.doValidation(value);//先用繼承類中的doValida tion方法驗證  
  18.             if (results.length > 0)//若是驗證時有錯,返回錯誤信息  
  19.                 return results;  
  20.             if(s.length>6)//自定義驗證,字符長度不超過6  
  21.             {  
  22.                 //記錄出錯信息  
  23.                 results.push(new ValidationResult(true,」text」,」StringTooLong」, 「字符長度超過6了」));  
  24.             }  
  25.             return results;  
  26.         }  
  27.     }  
相關文章
相關標籤/搜索