(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…)
使用方法
- loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);
- private function loadComplete(event:Event)
- {
- trace("done");
- addChild(loader);
- }
-
- xmlLoader.dataFormat=URLLoaderDataFormat.TEXT;
- xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded);
- private function xmlLoaded(event:Event) {
- try {
- myXML = XML(event.target.data);area.text=myXML;
- }catch (e:TypeError)
- {
- area.text="Load faild:\n"+e.message;
- }
- }
Loader
在使用Loader來加載數據時,添加偵聽事件時,注意必定要給Loader的 contentLoaderInfo屬性增長事件,而不是給Loader對象增長事件。
- var loader:Loader = new Loader();
- loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
- loader.contentLoaderInfo.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
- loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
(3)可使用SWFLoader和Loader兩個類來加載子應用程序,多數狀況下咱們使用SWFLoader。它是Loader的一個包裝類,提供了不少附加功能,使加載子應用程序更簡單。
SWFLoader有以下特徵:
支持flex的樣式和特效;而Loader類卻不支持任何固有的樣式和特效。
方便管理加載進度;若是使用Loader則首先要獲取LoaderInfo引用。
是一個UIComponent組件。SWFLoader它本身管理了全部子顯示對象,不須要添加多餘的代碼。
自動縮放顯示內容的大小
能夠加載Application之外的實現類,若是檢測到不是一個Application,會自動進行處理。
能夠處理不一樣的版本。Loader不支持加載不一樣的編譯版本
當使用Loader加載不是受信任區域的swf時,必須提供一個遮罩來從新定位,不然它會顯示在屏幕外面:
代碼
- import flash.display.*;
- import flash.net.URLRequest;
- var rect:Shape = new Shape();
- rect.graphics.beginFill(0xFFFFFF);
- rect.graphics.drawRect(0, 0, 100, 100);
- addChild(rect);
- var ldr:Loader = new Loader();
- ldr.mask = rect;
- var url:String = "http://www.unknown.example.com/content.swf";
- var urlReq:URLRequest = new URLRequest(url);
- ldr.load(urlReq);
- addChild(ldr);
SWFLoader加載外部swf是一個很好的方法,在進行Flex遊戲開發的時候,咱們一般會須要不少Flash提供的遊戲角色,這些角色能夠每一個都是一個單獨的swf,也能夠是存在於一個swf文件中的各個元件。兩種方法各有優劣:
1. 單獨的swf,每一個角色獨立性很強,能夠在須要的時候才加載。將來修改角色也不會影響到其它角色。可是會有不少的swf須要管理。
2. 每一個角色是一個元件,存在於一個swf中,這種方法比較容易管理資源,比較乾淨。可是修改一個角色都須要從新編譯swf,可能會誤操做影響其它的元件。並且一次加載全部角色,可能會加載許多沒必要要的元件,浪費帶寬。
兩種方法怎麼選擇,根據項目讀者根據如下幾個問題考慮:
1. 你的全部元件相互之間是否又不少公用元件?若是是的話,能夠考慮放到一個swf中,由於這樣會下降全部元件的文件量。
2. 你的全部元件是否都繼承同一些類,實現同一些接口,調用同一些類?若是是的話,能夠考慮放到一個swf中,這樣比較容易管理類包,並且下降swf的文件量,由於共有的類只編譯一次。
3. 你的全部元件是否徹底獨立,沒有任何關係?若是是的話,你能夠考慮每一個角色獨立的swf。
具體實現代碼以下:
- <?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="955" minHeight="600"
- creationComplete="init()"
- >
- <fx:Declarations>
- <!-- Place non-visual elements (e.g., services, value objects) here -->
- </fx:Declarations>
- <fx:Script>
- <![CDATA[
- import mx.controls.SWFLoader;
- import mx.core.UIComponent;
-
- private var swfLoader:SWFLoader = new SWFLoader();
- private function init():void{
- swfLoader.addEventListener(Event.COMPLETE,swfLoadComplete);
- swfLoader.load("assets/fishmomo.swf");
- }
- private function swfLoadComplete(e:Event):void{
-
- addElement(swfLoader);
- var swf:MovieClip = swfLoader.content as MovieClip;
-
-
- swf.fish.say("Load a swf");
-
-
- var FishSymbol:Object = swfLoader.content.loaderInfo.applicationDomain.getDefinition("Fish");
- var f:MovieClip = new FishSymbol() as MovieClip;
-
- f.say("Load a symbol within a swf");
- var ui:UIComponent = new UIComponent();
- ui.addChild(f);
- addElement(ui);
- }
- ]]>
- </fx:Script>
- </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 文件是相似 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措施。如:
- import flash.external.ExternalInterface ;
- ExternalInterface.call("JSFunction");
- ExternalInterface.call("JSFunctionWithParameters","myParameter");
- var result:String=ExternalInterface.call("JSFunctionWithReturn");
六、用JavaScript調用ActionScript函數
答:利用ExternalInterface.addCallback在JavaScript裏設置對Flex的回調措施而且在JavaScript裏調用ActionScript措施。
- AS:
- ExternalInterface.addCallback("function1",callback1);
- privatefunctioncallback1():void
- {
- Alert.show("callback1executed");
- }
- JS:
- container[swf].function1();
六、FileReference
答:
- browse(typeFilter:Array = null):Boolean
- cancel():void
- download(request:URLRequest, defaultFileName:String = null):void
- 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 你知道這種策略的使用方式是什麼嘛?以及優,缺點呢?
答:延遲實例化。優勢是能夠更快地加載組件,缺點是首次訪問其餘組件時,因爲須要從新加載此組件,可能會有必定的延遲。
十一、請試寫一個自定義的驗證組件
答:
- package myCompenent
- {
- import mx.validators.Validator;
- import mx.validators.ValidationResult;
- public class myValidators extends Validator
- {
- public function myValidators()
- {
- super();
- }
- private var results:Array;
-
- override protected function doValidation(value:Object):Array
- {
- var s:String = value as String;
- results = [];
- results = super.doValidation(value);
- if (results.length > 0)
- return results;
- if(s.length>6)
- {
-
- results.push(new ValidationResult(true,」text」,」StringTooLong」, 「字符長度超過6了」));
- }
- return results;
- }
- }