Application 이 작성되어 swf로 컴파일된 후 런타임에 실행되는 과정을 살펴 보기 위해 간단한 Application mxml을 만들고 컴파일 옵션에 다음을 추가합니다.
-keep-generated-actionscript=true
임의로 aa.mxml 이라는 Application을 만들어 컴파일을 시켜보면 여러 파일들이 generated 폴더에 자동으로 생성되는데 이 파일 중에 몇 가지 파일의 내용을 참고로 살펴봅니다. 관심 외 코드는 삭제하였습니다.
[aa.mxml]
(Application 파일)
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="onCreationComplete(event);">
<mx:Script>
<![CDATA[
private function onCreationComplete(event:Event):void
{
trace("onCreationComplete");
}
]]>
</mx:Script>
</mx:Application>
컴파일하면 자동 생성되는 파일의 내용입니다.
[aa-generated.as]
( aa.mxml 이 aa 클래스로 변환됩니다. Application 클래스를 상속 받았죠.)
[Frame] 메타데이터 태그는 컴파일러로 하여금 두 프레임을 가진 SWF를 만들도록 합니다. 그런 후 첫 번째 프레임에는 factory class와 factory class 에서 사용하는 class들, Embedded Asset을 집어넣고, 두 번째 프레임에는 그외 나머지 Embedded Asset들과 main class, main class에서 사용하는 다른 class들을 모두 집어 넣습니다. 말하자면 두 프레임을 가진 MovieClip 의 Document Class 가 바로 SystemManager인 것입니다. 그림으로 표현하자면 다음 그림과 같습니다. (http://www.bit-101.com/blog/?p=946 내용중 Frame 메타데이터 태그에 대한 내용이 있다. 참고 )
따라서 아래 aa 클래스는 먼저 _aa_mx_managers_SystemManager 클래스를 Document Class로 사용하여 위와 같은 구조를 갖추게 되고, 이제부터 이 SWF는 모든게 SystemManager의 통제하에서 이후 절차가 진행되게 되는 겁니다. 정작 Application 인스턴스는 SystemManager 클래스의 create()메서드를 통해 Application (aa 클래스)의 인스턴스를 만들고 있습니다.
{
[Frame(factoryClass="_aa_mx_managers_SystemManager")]
public function aa()
{
super();
mx_internal::_document = this;
mx_internal::_aa_StylesInit();
// <mx:Application> 태그의 attribute 내용 적용
this.layout = "absolute";
// 대부분 이벤트 설정은 아래와 같이 적용됩니다. 핸들러 메서드로 일정한 작명 규칙에 의해 자동으로 생성 된다는걸 예상이 드는군요.
this.addEventListener("creationComplete", ___aa_Application1_creationComplete);
}
override public function initialize():void
{
mx_internal::setDocumentDescriptor(_documentDescriptor_);
super.initialize(); // FlexEvent.PREINITIALIZE 이벤트가 발생함.
}
// 이벤트 호출
public function ___aa_Application1_creationComplete(event:mx.events.FlexEvent):void
{
// <mx:Application> 태그의 creationComplete="" 의 내용이 그대로 복사됩니다.
onCreationComplete(event);
}
// aa.mxml 의 <mx:Script> 태그 내용 (CDATA 내용)이 그대로 복사됩니다.
private function onCreationComplete(event:Event):void
{
trace("onCreationComplete");
}
}
Frame 메타데이터 태그를 제외하고는 별다른 사항이 없습니다. 어차피 Application 의 대부분은 사용자가 직접 작성한 코드에 의해 돌아갈 테니까요.
그럼 제일먼저 인스턴스화되는 factory class를 살펴보겠습니다. 아래 코드에는 나타나 있지는 않지만 SystemManager 에서는 실제로 Preloader 를 생성, 표현하고 로드 완료 시점에 Application 객체를 생성하는게 주된 일입니다.
[_aa_mx_managers_SystemManager-generated.as]
(SystemManager를 상속 받고 IFlexModuleFactory를 구현합니다.)
IFlexModuleFactory 는 동적으로 로드된 module이나 Flex applications 을 로드하여 초기 구동 시키기는 역할을 하는 요소를 포함합니다. create() 메서드는 SystemManager가 2프레임으로 넘어갔을 때 호출됩니다. 언급한대로 Application 클래스의 파생 클래스인 aa 클래스를 인스턴스화 하고 있습니다. 부모 클래스인 SystemManager의 코드 흐름 속에서 생성의 의무를 파생클래스에서 담당하도록 하는 전형적인 Factory Method 패턴 구조입니다.
{
public class _aa_mx_managers_SystemManager extends mx.managers.SystemManager implements IFlexModuleFactory
{
public function _aa_mx_managers_SystemManager()
{
FlexVersion.compatibilityVersionString = "3.0.0";
super();
}
override public function create(... params):Object
{
if ( params.length > 0 && !( params[0] is String ) )
return super.create.apply(this, params);
var mainClassName:String = params.length == 0 ? "aa" : String(params[0]);
var mainClass:Class = Class(getDefinitionByName(mainClassName));
if ( !mainClass ) return null;
var instance:Object = new mainClass();
if ( instance is IFlexModule )
( IFlexModule(instance) ).moduleFactory = this;
return instance;
}
override public function info():Object
{
return { compiledLocales: [ "en_US" ],
compiledResourceBundleNames: [ "containers", "core", "effects", "skins", "styles" ],
creationComplete: "onCreationComplete(event);",
currentDomain: ApplicationDomain.currentDomain,
layout: "absolute",
mainClassName: "aa",
…
}
}
…
}
}
SystemManager에 대한 자세한 사항은 여기 (http://vulcan9.tistory.com/18) 를 참고하세요
'Blog > Flex' 카테고리의 다른 글
SystemManager에 대하여 (4) | 2009.11.25 |
---|---|
stage, root에 대하여 (0) | 2009.11.24 |
Custom 컴포넌트에는 MX 컴포넌트를 못쓰는걸까? (2) | 2009.09.29 |
DataGrid 의 아이템 랜더러에 ColorPicker 컴포넌트 사용하기 (0) | 2009.09.25 |
달갑지 않은 internal build error!! (1) | 2009.09.22 |