Posted on

AIR記憶體監控工具 – Scout

記憶體監控相關工具

Scout是一款針對用以監控記憶體狀態的程式,它不但可以監控電腦上面的swf的記憶體狀況,也可以監看使用air開發,運行在手機上的app的記憶體和gpu使用狀況。
在Scout之前,了解swf的記憶體使用狀況有幾個方式

  1. 內建的Profile功能
    2013-10-11_161104
    Profile可以監控現有的FLASH裡每一個CLASS占的記憶體比例,預設的設定會忽略AS內建的類別。如果要打開的話,可以選擇選單列裡的Window=>Preferences=>Flash Builder=>Profiler=>Exclusion Filter或是Inclusion Filters去排除或增加要觀察的class種類。
    這個工具若是用按2013-10-11_171747的方式執行,則只能針對FLEX本身的專案來做觀察。如果專案架構是外部的SWF檔案,則可以先切換到Profile工作模式(如圖:2013-10-11_171854),然後選擇上方選單列的Profile=>Profile External Application=>New,去選擇要觀察的SWF檔案。
    有關這個工具的介紹請見: Flex記憶體監控程式-Profile
  2. windows的工作管理員
    監控執行緒的執行狀況,缺點是無法仔細的了解是那一個Class造成memory leak。
  3. Hi-ReS-Stats  (https://github.com/mrdoob/Hi-ReS-Stats)
    很常被見到的一個外掛程式碼,可以簡單的使用

    addChild( new Stats() );

    來觀察FPS的運行速度、記憶體的使用狀況是否正常。嵌入後會在畫面上多出如下圖這樣的資訊欄位
    hires_stats

  4. Scout  (http://gaming.adobe.com/technologies/scout/)
    最後就是今天要介紹的Adobe Scout工具,Adobe開發這個,主要是為了當開發者在使用Adobe AIR開發手機APP時,能夠更精準的掌握SWF運行的狀況以及GPU的狀況。因此Adobe官方便提供了這一項免費工具,讓APP開發者可以更仔細的監控效能的狀況。

Scout的優點

上面介紹了這麼多的工具,那麼Scout的優勢為何呢?

  1. 仔細(Details)
    Scout可以提供詳細、階層性的資訊,讓開發者一目了然自己的程式的GPU資訊及記憶體使用狀況。
    除了Profile的記憶體監控功能外,Scout還可以提供GPU運算的相關數字及報表。
    在上面所列的其他三項工具,只有Hi-ReS-Stats有顯示FPS,可以讓開發者了解FPS速度是否正常,可觀察何時影格速度會變慢,並檢查是否有什麼動畫讓畫面停住了。其餘的都只能單純的監控程式使用的記憶體狀況,而無法了解到動畫處理的記憶體使用狀況。
    在flash裡,動畫的運算、圖形處理等,在很多時候其實是造成畫面Lag的主要元兇,因此,或許很多時後我們會發現動畫不知為何播放速度變慢了,但是觀察Profile,記憶體的使用狀況卻很正常,這時很可能便是GPU Memory不足。
    有關要如何做才能提高動畫的效能,相關議題可以參考下面這篇文章:
    http://claire-chang.com/1063-提升Flash效能的幾個注意事項
  2. 可擴展性(Extensible)
    Adobe有提供相關的API,當原本Scout提供的資訊無法滿足需求時,開發者可以在ActionScript裡面寫程式,去自行丟出想觀察的額外資訊,並且只要幾行程式碼就可以做到。(請參見Telemetry類別)
  3. 跨平台(Cross-platform)
    可在Mac及Windows上運行,並能讓開發者開發Andriod及iOS APP時更容易觀察其效能狀況。
  4. 輕量化(Lightweight)
    Scout只有12MB,很輕並且運行的很快,並且可以運行於一般的Flash Player,不用使用Debug版本也可以。

 開始使用Scout

  1.  開啟SWFs的telemetry功能:將Enable detailed telemetry選項勾起來
    2013-10-11_181303
    PS: 此時大家可能會發現,咦~不對呀!我的Flex專案怎麼沒這個選項?
    是的,這個功能只有在AIR專案上才會有,非AIR專案是沒有這個選項的。
    所以,那一般Flash檔案要如何使用Scout呢?
    這時後就需要透過工具去開啟swf的Telemetry功能,詳細方法請見下面的文章:
    Enable Advanced Telemetry on Flex or old SWFs with SWF Scout Enabler
    簡單來說,便是下載SWF Scout Enabler,然後選取要觀察的SWF檔案,把它的Telemetry打開。
  2. 執行Scout,要觀察一個swf,可觀察遠端或在本機的檔案。是用Scout去監控運作在其他台電腦或是手機上的APP上的資訊會需要較多的設定。
    要執行Scout的電腦需要有

    • Flash Player 11.4 (plugin or standalone) or Adobe AIR 3.4.
    • The Adobe Scout desktop application.

    [觀察目標]
    (一) 本機檔案
    只要將Scout打開,就可以看到現在在電腦中正在運行的SWF檔案的相關資訊了。
    (二) 其他台電腦上檔案
    如果要去觀察在其他台電腦上運作的SWF檔案的效能狀況,可以經由.telemetry.cfg檔案的設定去做到(但需要同網域)。
    檔案位置如下:

    • MacOS: ~/.telemetry.cfg
    • Windows: %HOMEDRIVE%%HOMEPATH%\.telemetry.cfg

    在修改之後,.telemetry.cfg可能會長的像這樣
    TelemetryAddress=192.168.1.20:7934
    SamplerEnabled = true
    CPUCapture = true
    DisplayObjectCapture = false
    Stage3DCapture = false
    (三) 手機或移動裝置上的APP

    1. 確定手機與執行Scout的電腦在弄一個WIFI網路下
    2. 手機下載Adobe Scout檔案(iPhone在此下載Android在此下載)
    3. 打開手機上的Scout應用程式,這時他會搜尋同WIFI下的電腦,選擇我們執行Scout的電腦,然後按連線
    4. 到電腦裡選擇自己想看到的數據資料
    5. 運行有開啟Telemetry的手機APP應用程式
      adobe-scout-getting-started-fig04

    先介紹到這邊,下一篇會再介紹該如何去使用或設定Scout的相關功能。

參考資料:

  1. Getting started with Adobe Scout
  2. Enable Advanced Telemetry on Flex or old SWFs with SWF Scout Enabler
  3. Telemetry – AS3
  4. Adobe Scout
Posted on 1 Comment

AS3的事件傳遞機制(Event、dispatchEvent及addEventListener)

當事件被發送出來之後。Event一般來説都會有一個Flow。 Flow分三個部分:

  1. Capture(捕獲階段)
  2. Targeting(目標階段)
  3. Bubbling(冒泡階段)

其關係圖如下:(來源為http://www.adobe.com/devnet/actionscript/articles/event_handling_as3.html)

efAzj

值得一提的是,在FLASH裡,只有和UI相關的物件,會有上圖所示的目標及補獲階段的事件流

一般像是Timer、Loader事件,是直接進入目標階段,並不會有上圖所示的事件流的流程。
在宣告Event時,也可以先指定事件是否要完整的跑完全部的流程。

宣告事件的語法及及參數意義如下:

var event:Event = new Event(type, bubbles, cancelable);

參數說明(官方文件)

  1. type:String是要發送的事件的識別名稱EX:Event.COMPLETE
  2. bubbles:Boolean預設值是false,這個值是用來設定是否要有冒泡階段,如果傳false,代表他不會跑完全部的流程,只會從Capture到target階段就停止
  3. cancelable:Boolean預設值是false,這個值是用來設定是否這個事件可以被event.preventDefault();取消,如果設定為true的話,代表此事件是可以被取消的(稍候在dispatchEvent會更詳述這部份)。
    常用的可以取消的事件有(cancelable為true):   FocusEvent.MOUSE_FOCUS_CHANGEFocusEvent.KEY_FOCUS_CHANGETextEvent.TEXT_INPUT

而發送事件則是用這一段程式碼:

var result:Boolean = box.dispatchEvent(event);

在發送事件時,要注意,假使今天我們是在STAGE裡面有一個box物件,那當我們用box.dispatchEvent(event);
即使事件是用box發送的,事件還是會從stage > root > box這樣跑。(請見上圖)
假如在建立Event時,bubbles設為true,那在上圖跑的流程為stage > root > box > root > stage
而若bubbles設為false,跑的流程則是stage > root > box

當我們用root.dispatchEvent(event);
bubbles設為true,上圖跑的流程為stage > root > stage
bubbles設為false,流程為stage > root

由此可知,事件流只會到目標(Target),就會停止往下傳
假如今天box裡面有一個物件button,若是用box.dispatchEvent(event)
button物件是不會接到事件流的。(因為到目標階段便會開始bubbles或停止)
並且假如今天root裡同時有box和box2兩個物件,
假使我們用box.dispatchEvent(event),則box2也不會接到事件。

至於第三個在建立Event的參數cancelable,不論值是true或false,都不會影響事件流的流程。
那他的作用是做什麼的呢?

我們可以發現,dispatchEvent有回傳一個布林值,cancelable就是在影響這個布林值的傳回參數。
今天我們假如要創建一個物件,但是要讓使用者有權力去阻止這個事件發生後的後續發展時,可以這樣寫

if(this.dispathEvent(event)){
     trace("success!");
     //在這寫後續發展
}

假使使用者在監聽的途中呼叫 event.preventDefault();,並且EVENT的cancelable為true時,dispatchEvent回傳的值就會是false,便不會執行trace("success!");那塊區塊。但假使EVENT的cancelable為false時,不論你在事件執行中有沒有呼叫event.preventDefault(),dispatchEvent回傳的值就會是true

一般我們會在傳遞事件的途中,去將事件攔截下來。增加監聽事件的程式碼如下

box.addEventListener(MouseEvent.MOUSE_DOWN,parent1Event);

官網關於addEventListener的說明如下

addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void

傳入的參數意義如下:

  1. type(String):事件名稱
  2. listener(Function):要執行的Function
  3. useCapture(Boolean):這個和本篇要說的事件流有關,當今天傳入的值為true,則只能在補獲階段去抓取事件,在冒泡階段是聽不到的。如果將 useCapture 設置為 true,則偵聽器只在捕獲階段處理事件,而不在目標或冒泡階段處理事件。
    如果 useCapture 為 false,則偵聽器只在目標冒泡階段處理事件
    要在所有三個階段都偵聽事件,需註冊 addEventListener 兩次:一次將 useCapture 設置為 true,一次將 useCapture 設置為 false。當今天若useCapture為true時,並不會聽到target階段時的事件但若為false時,也可以聽到target階段時的事件

    假使今天我們用box.dispatchEvent(event);來發送事件,
    然後box的監聽事件的useCapture設為true。ex : box.addEventListener(MouseEvent.CLICK, rootClick, true);
    這樣rootClick事件並不會被呼叫到。

    若box的監聽事件的useCapture設為false 。ex : box.addEventListener(MouseEvent.CLICK, rootClick, false);
    這樣rootClick事件便被呼叫到。

  4. priority(int):若今天同時有很多個監聽器同時監聽同一事件,可用這個值來設定那一個監聽器應該被優先執行。數字愈高代表會愈快執行該事件偵聽程式。
  5. useWeakReference(Boolean):是否使用弱關連。若是用弱關連,當被監聽的物件所指到的變數被指向記憶體的其他地方,這個關係也會一併被取消(物件會被GC回收)。但如果傳進的值是false,當今天被監聽的物件的其他關連被指向別處時,該物件不會被GC回收,需要手動removeEventListener時,該物件才會被GC回收。

除了上述的幾個參數外,還有幾個函數可以中斷事件流的流程。
那就是stopPropagation()stopImmediatePropagation()

那這兩個函數有什麼差別呢?

下圖可以很清楚的解釋差異:
stopPropagation():會把同一階層的其他事件跑完才停止。
5MYe3

stopImmediatePropagation():立刻停止之後所有的事件流。
jleAX

假如今天box同時有兩個監聽函數如下

box.addEventListener(MouseEvent.MOUSE_DOWN,eventMouseDownHandler1,false,1);
box.addEventListener(MouseEvent.MOUSE_DOWN,eventMouseDownHandler2,false,2);

則由於priority值的關係,eventMouseDownHandler2會先被執行,eventMouseDownHandler1在之後才被呼叫
那若是在eventMouseDownHandler2裡面呼叫event.stopPropagation(),eventMouseDownHandler1還是會被執行,才將事件流中斷。
但是若在eventMouseDownHandler2裡面呼叫event.stopImmediatePropagation(),則eventMouseDownHandler1就不會被呼叫到

相關資源

  1. AS3.0的事件機制(詳細)
  2. AS3筆記-事件流(event flow)
  3. Event propagation
  4. Introduction to event handling in ActionScript 3.0
Posted on

Flex裡綁定(Bindable)相關函數及使用方式

在flex裡,最強大的標籤應該就是[Bindable]的綁定標籤了
因為某次的需求,我需要研究將Bindable綁定至函數
也順便研究了ChangeWatcher和BindingUtils的使用

【BindingUtils】
官方的說明在此:
http://help.adobe.com/zh_TW/FlashPlatform/reference/actionscript/3/mx/binding/utils/BindingUtils.html
這是Flex內綁定的工具,裡面有兩個屬性,一個是綁定到函數(bindSetter),另一個則是綁定到某物件的某屬性(bindProperty)

使用範例如下
1. 綁定到函數(bindSetter)










2. 綁定到某物件的某屬性(bindProperty)










【ChangeWatcher】
官方的說明在此:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/binding/utils/ChangeWatcher.html
因為此次我們要綁定的函數裡是有帶多個參數的,因此BindingUtils的bindSetter便無法使用
這時就需要使用BindingUtils所用的ChangeWatcher來自己做綁定的動作
ChangeWatcher的使用方式如下
var model:Model = new Model();
watcherInstance = ChangeWatcher.watch(model,[“totalItems”],itemsChanged);
根據官方文件watch的傳入的東西依序為”要綁定的物件”、”要綁定的屬性”、”要綁定的函數”

下面便是我根據這些所寫的小範例
MyBindingUtils.as
package {
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.system.Capabilities;
import flash.utils.getTimer;

import mx.binding.utils.ChangeWatcher;
import mx.controls.Alert;
import mx.resources.ResourceManager;

public class MyBindingUtils extends EventDispatcher {

private static var _objs:MyBindingUtils;

public static function getInstance():MyBindingUtils {
if (_objs == null) {
_objs = new MyBindingUtils();
}
return _objs;
}

public function changeLanguage(lang:String):void {
ResourceManager.getInstance().localeChain = [lang, “en_US”];
this.dispatchEvent(new Event(“ChangeLanguage”));
}

[Bindable(event=”ChangeLanguage”)]
public function getString(type:String, key:String, parameters:Array = null, locale:String = null):String {
return ResourceManager.getInstance().getString(type, key, parameters, locale);
}

public function bindString(target:Object, prop:String, type:String, key:String, parameters:Array = null):String {
var w:ChangeWatcher = ChangeWatcher.watch(this, [“getString”], null);
var result:String = getString.apply(null, [type, key, parameters]);
if (w != null) {
var invoke:Function = function(event:*):void
{
result = getString.apply(null, [type, key, parameters]);
target[prop] = result;
};
w.setHandler(invoke);
invoke(null);
}
return result;
}
}
}

完整範例檔案可按此下載

Posted on

AS3.0中製作直式書寫的方式

在as3.0中有 FTE可針對文字去測量其寬度、高度等
針對個別的文字去做處理
相關官網的說明可見此
http://help.adobe.com/en_US/ActionScript/3.0_ProgrammingAS3/WS6C0BB8ED-2805-467a-9C71-F9D757F33FB6.html

ElementFormat是定義文字的相關屬性(字型、大小、顏色等等)
然後再new一個TextElement設定文字格式和文字內容
再將其放到一個TextBlock裡面

TextBlock裡面則有許多相關的操作函數
可以對個別的文字做旋轉、定位等等
http://livedocs.adobe.com/flex/3_cn/langref/flash/text/engine/TextBlock.html
詳細的手冊說明在上面

裡面的lineRotation將角度設為九十度(TextRotation.ROTATE_90)時
文字就會呈現傳統的中文直式書寫方式呈現

下面的是將文字改為直式文字的範例程式

package {
import flash.display.Sprite;
import flash.text.engine.FontDescription;
import flash.text.engine.TextBlock;
import flash.text.engine.TextElement;
import flash.text.engine.TextLine;
import flash.text.engine.TextRotation;
import flash.text.engine.ElementFormat;

public class TextBlock_lineRotationExample extends Sprite {

public function TextBlock_lineRotationExample():void {
var s:String = “一向批判電影不會「口下留情」的大陸媒體,竟在李安導演《少年PI的奇幻漂流》內地上映後,於中國最大入口網站搜狐,罕見大讚道:『影片美輪美奐的視覺奇觀,身臨其境的3D效果。』”;

var fontDescription:FontDescription = new FontDescription(“MS Mincho”);
var format:ElementFormat = new ElementFormat();
format.fontSize = 15;
format.fontDescription = fontDescription;

var textElement:TextElement = new TextElement(s, format);
var textBlock:TextBlock = new TextBlock();
textBlock.content = textElement;
textBlock.lineRotation = TextRotation.ROTATE_90;

var linePosition:Number = this.stage.stageWidth – 120;
var previousLine:TextLine = null;

while (true) {
var textLine:TextLine = textBlock.createTextLine(
previousLine,
300);
if (textLine == null)
break;
textLine.y = 30;
textLine.x = linePosition;
linePosition -= 24;
addChild(textLine);
previousLine = textLine;
}
}
}
}

Posted on

在flex4裡用spark建置可拖動panel

在flex4裡面的spark組件的panel是沒有內建拖動的功能的
因此若我們希望這物件要可以被拖動
我們必須要去自己實做當使用者拖動topGroup的區塊時的拖動動作

範例程式碼如下:
package components
{
import flash.events.MouseEvent;

import mx.managers.DragManager;

import spark.components.Group;
import spark.components.Panel;

/**
* A simple extension of the Spark Panel component
* that enables dragging.
*/
public class DraggablePanel extends Panel
{
//————————————–
// Constructor
//————————————–

public function DraggablePanel()
{
super();
}

//————————————–
// Skin Parts
//————————————–

/**
* The skin part that represents the title bar of the underlying Panel.
* NOTE: The default PanelSkin already has this, it’s just not defined as a skinPart in the Panel class.
* We want it so that we can capture dragging.
*/
[SkinPart(required=”true”)]
public var topGroup:Group;

//————————————–
// Overridden Methods
//————————————–

protected override function partAdded( partName:String, instance:Object ) : void
{
super.partAdded( partName, instance );

if (instance == topGroup)
{
Group( instance ).addEventListener( MouseEvent.MOUSE_DOWN, topGroup_mouseDownHandler );
Group( instance ).addEventListener( MouseEvent.MOUSE_UP, topGroup_mouseUpHandler );
}
}

protected override function partRemoved( partName:String, instance:Object ) : void
{
super.partRemoved( partName, instance );

if (instance == topGroup)
{
Group( instance ).removeEventListener( MouseEvent.MOUSE_DOWN, topGroup_mouseDownHandler );
Group( instance ).removeEventListener( MouseEvent.MOUSE_UP, topGroup_mouseUpHandler );
}
}

//————————————–
// Event Handlers
//————————————–

protected function topGroup_mouseDownHandler( event:MouseEvent ):void
{
if ( !DragManager.isDragging )
startDrag();
}

protected function topGroup_mouseUpHandler( event:MouseEvent ):void
{
stopDrag();
}
}

Posted on

如何在flex4裡自製resize事件

首先resize事件是針對該元件大小被縮放時才會產生
所以要在根元件去監聽resize的事件

很必需注意的一點,是flex4的spark元件預設會自動無視超出範圍大小的東西
因此會發現當我們把視窗縮小時,
因為超出的大小被無視了
無法偵聽到resize事件
這時候我們要在根容器上加上 clipAndEnableScrolling=”true”屬性
這個屬性主要是告訴我們要不要自動無視超出的範圍
group的預設值是false 也就是無視他
因此我們要先將 clipAndEnableScrolling設定為true
才可以偵聽到縮小視窗的事件

Posted on

ResourceManager動態載入多國語系的實現

事前準備工作
1.[撰寫Ant編譯時所使用的XML檔]
依照原有的XML去設定自己的SDK的位置,並且寫入要載入的語言檔

<?xml version="1.0" encoding="utf-8"?>
    <project name="Example resource bundle builder" basedir="." default="main">
    <!--這邊應設定為自己電腦的flex sdk的位置-->
    <property name="FLEX_HOME" value="C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.0" />
    <property name="APP_ROOT" value="${basedir}"/>
    <!--這邊需要載入ant編譯as檔案所需的flexTasks.jar以及所有相關編譯所需的函式庫-->
    <taskdef resource="flexTasks.tasks" >
        <classpath> <pathelement path="${FLEX_HOME}/ant/lib/flexTasks.jar"/>
            <pathelement path="${FLEX_HOME}/lib/flexTasks.jar"/>
            <fileset dir="${FLEX_HOME}/lib">
                <include name="**/*.jar"/>
            </fileset>
        </classpath>
    </taskdef>
    <!--定義所有的語言-->
    <target name="main">
        <antcall target="en_US"></antcall>
        <antcall target="zh_TW"></antcall>
    </target>
    <target name="en_US">
        <mxmlc>
            <locale>en_US</locale>
            <source-path>locale/{locale}</source-path>
            <include-resource-bundles>test</include-resource-bundles>
            <output>src/Resources_en_US.swf</output>
        </mxmlc>
    </target>
    <target name="zh_TW">
        <mxmlc keep-generated-actionscript="true">
            <allow-source-path-overlap>true</allow-source-path-overlap>
            <locale>zh_TW</locale>
            <source-path>locale/{locale}</source-path>
            <!--載入相關的函式庫-->
            <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                <include name="libs" />
                <include name="locale/{locale}" />
            </compiler.library-path>
            <!--定義要載入的語言檔案(可以用很多檔案)-->
            <include-resource-bundles>test</include-resource-bundles>
            <!--<include-resource-bundles>other</include-resource-bundles>-->
            <output>src/Resources_zh_TW.swf</output>
        </mxmlc>
    </target>
</project>

2.[設定Ant環境]
(a)Help->Software Updates更新flash builder的Ant編輯程式
(b)Windows->Show View->Other->Ant->Ant把視窗叫出來
(c)按Ant編譯視窗最左邊的Add Buildfiles,選擇剛剛寫的xml
(d)RUN他

3.[設定要產出的flex專案檔的編譯locale參數]
如果是要中文+英文則為-locale en_US zh_TW,如果少了這個動作在變語言時會發生缺少核心語言CORE檔案的問題。

4. locale檔副檔名是.properties

====================================
1. flex版本的實現及範例下載
http://www.nbilyk.com/flex-localization-example

2. 為flash builder安裝ant
http://www.judahfrangipane.com/blog/2007/12/13/flex-builder-3-ant-support/

3. 官方關於ResourceManager的類別資料
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/resources/ResourceManager.html

4. 在flash裡實現多國語系
http://ticore.blogspot.com/2010/07/as3-project-multi-languages.html

5. 各種實現方式
http://blog.csdn.net/fireson/archive/2010/01/12/5181343.aspx

[學習經歷]
首先先至[flex版本的實現及範例下載]下載多國語系範例
然後到[為flash builder安裝ant]實際編譯ResourceManager的語言檔為swf
再依範例自行試看看如何實現

Posted on

把 Flex SDK 4 整合進 Flex Builder 3

 
Flex SDK 4 已經出來了,可惜還沒有 Flex Builder 4。不過沒關係,看到國外有些人把 Flex SDK 4 整合進去 Flex Builder 3,照樣可以視覺化開發應用程式。以下,野部就詳列操作步驟:

一、下載 Flex SDK 4:
http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4
Adobe Flex SDK (ZIP  82MB)

二、確認 Flash Player 的版本是 10 以上,預設的 9 是不可以搭配 Flex 4 使用的:
http://www.adobe.com/products/flash/about/
記下這一行 「You have version 10,0,12,36 installed」。

三、安裝 Flex SDK 4:

將 Flex SDK 4 解壓縮,並且根據版本序號命名為 4.0.0。將此資料夾移動到 C:\Program Files\Adobe\Flex Builder 3\sdks。此時可以看到之前已經有 2.0.1,3.2.0 兩個資料夾了。

四、設定 Flex Builder 3 呼叫 Flex SDK 4:
首先,先進入「功能表選單 => Project => Properties => Flex Compiler 」,看到右上角「Configure Flex SDKs」,進入之後,我們可以看到,已經有 Flex 2.0.1 Hotfix 3 和 Flex 3.2。現在請按下 Add,Flex SDK location 指向 C:\Program Files\Adobe\Flex Builder 3\sdks\4.0.0,Flex SDK name 會自動出現 Flex 4.0,如果沒有,請自行手動輸入。增加完畢後,請在 Flex 4.0 之前打勾。

五、設定專案使用 Flash Player 10 執行:
通常 Flex Builder 3 的專案都是放在 「我的文件 => Flex Builder 3」 的資料夾下。進入想要用 Flex SDK 4 開發的專案資料夾。用記事本打開 「.actionScriptProperties」檔案,找到「htmlPlayerVersion」,把版本從「9.x.x」改成「10.0.12」。此處原本是可以從 Builder 來改,但是不知道為何改了之後無法存檔,只好用記事本改。

六、測試成功與否,輸入:

   
如果沒有錯誤訊息,表示整合成功。

注意事項:

  1. 每次開一個新專案或者舊專案要用 Flex SDK 4 來建構的話,都必須重複執行步驟五,否則 Flex Builder 3 呼叫預設的 Flash Player 9,會產生錯誤訊息。
    http://blog.shortfusion.com/index.cfm/2008/12/27/Flex4Gumbo-Error-1046-Type-Not-Found-Matrix3d–Easy-Fix
  2. Flex 4 和 Flex 3 的 buy CBD products 的 XML 命名空間不太一樣,所以語法上也要有些對應調整,可以參考下面這個範例,要改的地方包含 xmlns、所有標籤前方的 mx: 也都不見了。
    http://blog.flexexamples.com/2008/10/22/setting-text-alignment-on-an-fxtextarea-control-in-flex-gumbo/
  3. 另外,當專案最後產出 swf  的時候,可以在 「功能表選單 => Project => Properties => Flex Compiler 」把 「 -locale en_US 」改成「-locale en_US -debug=false 」可讓每個 swf 減少100KB。但是,這樣做會把除錯訊息整個隱藏,要注意。
  4. 此外,切換到 Design Mode 時會出現 warning 訊息,根據討論區的回應,看來目前 Flex 開發團隊還在處理當中。
    http://www.adobe.com/cfusion/webforums/forum/messageview.cfm?forumid=72&catid=669&threadid=1407689&enterthread=y