ActionScript 3.0의 ApplicationDomain은 로드한 SWF파일 내부에 정의된 Class를 참조하는데 유용하게 쓰인다.
ApplicationDomain은 현재 hasDefinition(name:String):Boolean 과 getDefinition(name:String):Object 등 2개의 public 메소드를 지원한다. 이 메소드를 이용하여 ApplicationDomain내 정의된 클래스 정의 유무를 알 수 있고 그에 대한 참조를 얻을 수 있다. 다음은 사용 예이다.
var myInstance:DisplayObject = new (ApplicationDomain.currentDomain.getDefinition("com.flassari.MyClass"));
위 코드의 경우 현재 애플리케이션의 ApplicationDomain상에 정의된 com.flassari.MyClass 클래스의 정의를 읽어와 DisplayObject 객체를 만드는 것이다. 사용하기 매우 쉽다. 그러나 클래스의 이름을 알고 있다는 전재하에 쓰일 수 있는 방법이다. 그럼 ApplicationDomain 내에 정의된 이름을 알지 못하는 클래스들의 이름을 목록을 알고 싶을 때는 어떻게 해야할까? 불행히도 ApplicationDomain 클래스는 이것을 지원해주고 있지 않다. ApplicationDomain.getAllDefinitions():Array 와 같은 메소드가 지원된다면 좋을 텐데 말이다.
해결방법이 있다. 바로 여기에서 소개하는 SwfClassExplorer 클래스를 이용하면 된다. 사용방법은 매우 단순하다. 하나의 static 메소드인 getClasses(bytes:ByteArray):Array 를 이용하면 된다. 아래 코드는 간단한 사용예제이다.
public function init():void { // Load the swf var urlLoader:URLLoader = new URLLoader(); urlLoader.dataFormat = URLLoaderDataFormat.BINARY; urlLoader.addEventListener(Event.COMPLETE, onSwfLoaded); urlLoader.load(new URLRequest("pathToSwf")); } private function onSwfLoaded(e:Event):void { // Get the bytes from the swf var bytes:ByteArray = ByteArray(URLLoader(e.currentTarget).data); // And feed it to the SwfClassExplorer var traits:Array = SwfClassExplorer.getClasses(bytes); for each (var trait:Traits in traits) { trace(trait.toString()); // The full class name } }
이는 매우 유용함을 알 수 있다. SWF를 Loader가 아닌 URLLoader로 로드했음을 볼 수 있다. 그리고 실제 DisplayObject 객체를 생성하기 위해 다음과 같이 코딩하면 되겠다.
private var _loader:Loader; public function init():void { var urlLoader:URLLoader = new URLLoader(); urlLoader.dataFormat = URLLoaderDataFormat.BINARY; urlLoader.addEventListener(Event.COMPLETE, onSwfLoaded); urlLoader.load(new URLRequest("pathToSwf")); } private function onSwfLoaded(e:Event):void { var bytes:ByteArray = ByteArray(URLLoader(e.currentTarget).data); var traits:Array = SwfClassExplorer.getClasses(bytes); for each (var trait:Traits in traits) { trace(trait.toString()); // The full class name } selectedClassName = traits[0]; _loader = new Loader(); var loaderContext:LoaderContext = new LoaderContext(); _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderInit); _loader.loadBytes( bytes, loaderContext ); } private function onLoaderInit(event:Event){ var obj:Object; try { obj = new (_loader.contentLoaderInfo.applicationDomain.getDefinition(selectedClassName )); } catch (e:Error) { trace( "Can't instantiate class:\n" + e.toString() ); } if (obj != null && obj is DisplayObject) { addChild( DisplayObject(obj) ); } }
결국 Binay형태로 받아온 SWF를 Loader클래스의 loadBytes()메소드를 이용해 비동기적으로 로드처리한 뒤에 Loader.contentLoaderInfo.applicationDomain의 getDefinition() 메소드를 이용해 객체를 생성하는 방식이다.
아쉬운 점은 여기서 loadBytes()를 이용한 비동기적 처리가 아닌 동기적 처리를 통해 클래스 참조를 얻어낼 수 있다면 더욱 좋을 것 같다. 사실 이 부분을 찾다가 이 예제를 찾아내게 된건데 매우 유용해서 포스팅 한 것이다.
세부적인 예제 및 소스는 아래 출처를 참고한다.
출처
소스
위 출처에서 소스를 다운받을 수 없으면 아래 링크로 다운받는다.
'비공개 > Adobe Flex, ActionScript 3.0' 카테고리의 다른 글
ActionScript 3.0 함수의 오버로딩(Overloading) 해결하기 (3) | 2009.05.15 |
---|---|
[Flex/Flash] ActionScript 3.0 으로 브라우저 종류 알아내기 (5) | 2009.05.15 |
[Flash/Flex/AS3] AVM1을 AVM2로 변환하는 AVM2Loader (0) | 2009.05.15 |
[Flex/Flash] ShowSpace 사진 공유 플레이어 (0) | 2009.05.15 |
ActionScript 3.0 Code 라이브러리 모음 (2) | 2009.05.15 |