当前位置: 首页 > 工具软件 > Flex SDK > 使用案例 >

FLEX SDK 源码

葛宏爽
2023-12-01

Flex 4 SDK源码浅析!

如大家要转载,请保留本人的版权:
/*
*Description:PV3D类继承体系结构

*Auther:崇崇-天真的好蓝啊
*MSN:chongchong2008@msn.com
*Blog:chongchong2008
*Dates:2009-06-02
*Copyright:ChongChong2008 YiChang HuBei China
*/

 

Flex 4 SDK源码浅析!

 


最近下了Flex 4 SDK (flex_sdk_4.0.0.7219_mpl_src)的源代码
此目录下包含如下相关的几个部分:

1。mx 核心 frameworks,它在以下目录可以找到
flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> framework --> src --> mx

2。rpc frameworks,它在以下目录可以找到
flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> rpc --> src --> mx

3。air framework,它在以下目录可以找到
flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> airframework --> src --> mx

4。皮肤相关,它在以下目录可以找到
flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> haloclassic --> src

一。熟悉Flex SDK
Flex SDK真的很庞大,包罗万象,一开始真的很难入手,不知道从哪里开始读。
首先是熟悉Flex定义的基本接口,把各个接口都看一遍。就是在flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> framework --> src --> mx -->core 里面的基本接口文件,熟悉Flex的UIComponent组件,Container容器,特别是要熟悉Application类(如何与SystemManager类建立联系,组建是如何进入队列,怎样延迟调用)。

熟悉UICommpontent
public function callLater(method:Function,args:Array /* of Object */ = null):void {
        methodQueue.push(new MethodQueueElement(method, args));
        var sm:ISystemManager = systemManager;
        if (sm && (sm.stage || sm.useSWFBridge()))
        {
            if (!listeningForRender)
            {
                sm.addEventListener(FlexEvent.RENDER, callLaterDispatcher);
                sm.addEventListener(FlexEvent.ENTER_FRAME, callLaterDispatcher);
                listeningForRender = true;
            }
            if (sm.stage)
                sm.stage.invalidate();
        }
    }


熟悉FlexModuleFactory类的运作方式,系统单件类的注册,如何加载模块。

  addFrameScript(docFrame, docFrameHandler);

  // Frame 1: module factory
  // Frame 2: document class
  // Frame 3+: extra classes
         for (i = docFrame + 1; i < totalFrames; i++){
      addFrameScript(i, extraFrameHandler);
  }


接下来看Flex定义的管理接口,在flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> framework --> src --> mx -->managers里面,这个要先熟悉,才能知道Application是怎么运行的,这里的东西有些复杂,得认真看。特别是要认真的读SystemManager这块,这块就如同基本接口里的UIComponent一样重要。

还有一些概念要熟悉,需要知道什么是document,swfRoot,sandboxRoot,topLevelSystemManager。

 

Flex Application 运行:

=======================================================
FlexApplicationBootstrap.as
==================================
package mx.core{
import flash.display.DisplayObject;
import flash.events.Event;
import mx.events.FlexEvent;

[ExcludeClass]
public class FlexApplicationBootstrap extends FlexModuleFactory{
 include "../core/Version.as";
 public function FlexApplicationBootstrap(){
  addEventListener("ready", readyHandler);  
  super();
       }

       public function readyHandler(event:Event):void{
           removeEventListener("ready", readyHandler);       
     var o:Object = create();       
     if (o is DisplayObject){
               addChild(DisplayObject(o));
   o.dispatchEvent(new FlexEvent(FlexEvent.APPLICATION_COMPLETE));
     }

        }
    }
}


=======================================================
FlexModuleFactory.as
=======================================================
package mx.core{
[ExcludeClass]
/**
 *  @private
 */
public class FlexModuleFactory extends MovieClip implements IFlexModuleFactory, ITextLineCreator{

        private static const INIT_STATE:int = 0;
 private static const RSL_START_LOAD_STATE:int = 1;
 private static const APP_LOAD_STATE:int = 2;
 private static const APP_START_STATE:int = 3;
 private static const APP_RUNNING_STATE:int = 4;
 private static const ERROR_STATE:int = 5;
 private static const RSL_LOADING_STATE:int = 6;

 public function FlexModuleFactory(){
     super();
     var rsls:Array = info()["rsls"];
     var cdRsls:Array = info()["cdRsls"];
         
     // Put cross-domain RSL information in the RSL list.
          var rslList:Array = [];
          var n:int;
          var i:int;
    if (cdRsls && cdRsls.length > 0){
  var crossDomainRSLItem:Class = Class(getDefinitionByName("mx.core::CrossDomainRSLItem"));
  n = cdRsls.length;
  for (i = 0; i < n; i++){
    var cdNode:Object = new crossDomainRSLItem(
     cdRsls[i]["rsls"],
     cdRsls[i]["policyFiles"],
     cdRsls[i]["digests"],
     cdRsls[i]["types"],
     cdRsls[i]["isSigned"]);
    
    rslList.push(cdNode);    
  }   
     }
     if (rsls != null && rsls.length > 0){
   n = rsls.length;
   for (i = 0; i < n; i++)
   {
       var node:RSLItem = new RSLItem(rsls[i].url);
    rslList.push(node);
   }
     }

            rslListLoader = new RSLListLoader(rslList);

  mixinList = info()["mixins"];

  stop();
       
  loaderInfo.addEventListener(Event.COMPLETE, moduleCompleteHandler);

     var docFrame:int = totalFrames == 1 ? 0 : 1;

  addFrameScript(docFrame, docFrameHandler);

  // Frame 1: module factory
  // Frame 2: document class
  // Frame 3+: extra classes
     for (i = docFrame + 1; i < totalFrames; i++)
     {
      addFrameScript(i, extraFrameHandler);
  }

  timer = new Timer(100);
  timer.addEventListener(TimerEvent.TIMER, timerHandler);
  timer.start();

        update();
    }

    public function create(... params):Object
    {
     var mainClassName:String = info()["mainClassName"];
    
  if (mainClassName == null)
     {
            var url:String = loaderInfo.loaderURL;
            var dot:Number = url.lastIndexOf(".");
            var slash:Number = url.lastIndexOf("/");
            mainClassName = url.substring(slash + 1, dot);
     }
   
        var mainClass:Class = Class(getDefinitionByName(mainClassName));

        return mainClass? new mainClass() : null;
    }

    public function info():Object
    {
        return {};
    }

 private function docFrameHandler(event:Event = null):void
 {
  // Register singleton classes.
  // Note: getDefinitionByName() will return null
  // if the class can't be found.

  Singleton.registerClass("mx.managers::IBrowserManager",
   Class(getDefinitionByName("mx.managers::BrowserManagerImpl")));

        Singleton.registerClass("mx.managers::ICursorManager",
   Class(getDefinitionByName("mx.managers::CursorManagerImpl")));

        Singleton.registerClass("mx.managers::IDragManager",
   Class(getDefinitionByName("mx.managers::DragManagerImpl")));

        Singleton.registerClass("mx.managers::IHistoryManager",
   Class(getDefinitionByName("mx.managers::HistoryManagerImpl")));

        Singleton.registerClass("mx.managers::ILayoutManager",
   Class(getDefinitionByName("mx.managers::LayoutManager")));

        Singleton.registerClass("mx.managers::IPopUpManager",
   Class(getDefinitionByName("mx.managers::PopUpManagerImpl")));

  Singleton.registerClass("mx.resources::IResourceManager",
   Class(getDefinitionByName("mx.resources::ResourceManagerImpl")));

        Singleton.registerClass("mx.styles::IStyleManager",
   Class(getDefinitionByName("mx.styles::StyleManagerImpl")));

        Singleton.registerClass("mx.styles::IStyleManager2",
   Class(getDefinitionByName("mx.styles::StyleManagerImpl")));

        Singleton.registerClass("mx.managers::IToolTipManager2",
   Class(getDefinitionByName("mx.managers::ToolTipManagerImpl")));

  appReady = true;
       
        // The resources must be installed before update() creates components
  // (such as DateChooswer) that might need them immediately.
  installCompiledResourceBundles();
  
  update();
       
  if (currentFrame < totalFrames)
            deferredNextFrame();
    }


    private function deferredNextFrame():void
    {
        if (currentFrame + 1 <= framesLoaded)
  {
            nextFrame();
  }
        else
        {
            // Next frame isn't baked yet, we'll check back...
      nextFrameTimer = new Timer(100);
      nextFrameTimer.addEventListener(TimerEvent.TIMER,
           nextFrameTimerHandler);
      nextFrameTimer.start();
        }
    }

 private function extraFrameHandler(event:Event = null):void
 {
     var frameList:Object = info()["frames"];

     if (frameList && frameList[currentLabel])
     {
         var c:Class;
         try
         {
             c = Class(getDefinitionByName(frameList[currentLabel]));
             c["frame"](this);
         }
         catch(e:Error)
         {
   }
     }

     if (currentFrame < totalFrames)
            deferredNextFrame();
 }

 private function timerHandler(event:TimerEvent):void
 {
     if (totalFrames > 2 && framesLoaded >= 2 ||
   framesLoaded == totalFrames)
  {
            appLoaded = true;
  }
  
  update();
    }

 private function nextFrameTimerHandler(event:TimerEvent):void
 {
     if (currentFrame + 1 <= framesLoaded)
     {
         nextFrame();
            nextFrameTimer.removeEventListener(TimerEvent.TIMER,
              nextFrameTimerHandler);
         // stop the timer
         nextFrameTimer.reset();
        }
    }
}

}

 


二。Flex继承体系

比较重要的类和接口在flex_sdk_4.0.0.7219_mpl_src -- > frameworks -- > projects --> framework --> src --> mx -->core

1。接口继承体系,从底层接口到高层接口如下:

IFlexDisplayObject --> IBitmapDrawable, IEventDispatcher
IUIComponent --> IFlexDisplayObject
IContainer --> IUIComponent
IDeferredInstantiationUIComponent --> IUIComponent
IButton --> IUIComponent

IBorder
IRectangularBorder -- > IBorder

ILayoutElement --> IEventDispatcher

IID
IRawChildrenContainer
IChildList

IConstraintClient
IDataRenderer
IEmbeddedFontRegistry
IFontContextComponent
IFactory
IFlexModule
IFlexModuleFactory
IInvalidating
IProgrammaticSkin

对flash本身的包装
IDisplayObjectInterface
IInteractiveObjectInterface
IDisplayObjectContainerInterface

内部命名空间
mx_internal

2。类继承体系

FlexSprite --> Sprite
UIComponent --> FlexSprite implements IAutomationObject, IChildList, IConstraintClient,
                                      IDeferredInstantiationUIComponent, IFlexDisplayObject, IFlexModule, IID,
                                      IInvalidating, ILayoutManagerClient, IPropertyChangeNotifier,
                                      IRepeaterClient, IStateClient, IAdvancedStyleClient, IToolTipManagerClient,
                                      IUIComponent, IValidatorListener, IVisualElement, ILayoutElement

Container --> UIComponent implements IContainer, IDataRenderer,
                                     IFocusManagerContainer, IListItemRenderer,
                                     IRawChildrenContainer, IChildList, IVisualElementContainer

LayoutContainer --> Container implements IConstraintLayout
LayoutManager --> EventDispatcher implements ILayoutManager

 

ClassFactory implements IFactory

全局类:
FlexGlobals
UIComponentGlobals
ContainerGlobals
SystemManagerGlobals
Singleton(Flex单件类,静态类型,很多地方都会引用到)

应用程序相关:
Application --> LayoutContainer
FlexApplicationBootstrap --〉FlexModuleFactory

系统管理相关:
ISystemManager --> IEventDispatcher, IChildList, IFlexModuleFactory
SystemManager --> MovieClip implements IChildList, IFlexDisplayObject, IFlexModuleFactory,
                                ISWFBridgeProvider, ISystemManager, ITextLineCreator
SystemManagerProxy --> SystemManager
SystemRawChildrenList implements IChildList

拖动管理相关:
IDragManager
DragManagerImpl implements IDragManager
DragManager
DragProxy --> UIComponent
DragSource
DragEvent --> MouseEvent

其他还有ToolTipManager,CursorManager,FocusManager,PopUpManager,LayoutManager,BrowserManager,HistoryManager

 

 

三。事件钩子,函数调用队列以及单件

Flex SDK内部大量的用到单件,事件钩子,队列调用。

Singleton.registerClass(
    "mx.resources::IResourceManager",
    Class(getDefinitionByName("mx.resources::ResourceManagerImpl"))
);

。。。。。未完

 类似资料: