Flex 加载动态加载类库解决getDefinitionByName的问题【原创】
做Flex的人都知道Flex API的getDefinitionByName方法类似于java中的Class.forName(),通过字符串动态反射出一个类,但是Flash Builder处于对swf体积的考虑,在工程项目中若未用到某些类,是不会编译到swf中,这就会导致用getDefinitionByName方法的时候,必须把该类声明一下或者是把类定义出来像这样:
上下两种均可,按照喜好任选一种.
但是如果有一种需求,希望从配置文件中动态实例化一些自定义组件,若用这种方式就会出现一些莫名其妙的定义或声明,而且如果需要动态生成的类很多的,则会出现大量冗余的代码.
下面介绍如果动态加载类库:
第一步,新建一个类库项目命名为ReflectComponentLib
第二步,在类库中创建一个Circle继承Sprite,代码如下:
View Code
1 package com.test 2 { 3 import flash.display.Sprite; 4 5 public class Circle extends Sprite 6 { 7 public function Circle() 8 { 9 super(); 10 draw(); 11 } 12 13 private function draw():void 14 { 15 graphics.beginFill(0xFF0000,1); 16 graphics.drawCircle(0,0,10); 17 graphics.endFill(); 18 } 19 } 20 }
第三步,将库项目生成swc,用WinRar方式打开,打开后会发现里面有两个文件,library.swf和catalog.xml
第四步,创建一个测试测试项目,web和air项目均可,然后贴上这样的代码:
View Code
1 <?xml version="1.0" encoding="utf-8"?> 2 <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 3 xmlns:s="library://ns.adobe.com/flex/spark" 4 creationComplete="creationCompleteHandler(event)" 5 xmlns:mx="library://ns.adobe.com/flex/mx"> 6 <fx:Script> 7 <![CDATA[ 8 import mx.events.FlexEvent; 9 10 private var loaded:Object = {}; 11 12 protected function creationCompleteHandler(event:FlexEvent):void 13 { 14 var ldr:Loader = new Loader(); 15 var urlReq:URLRequest = new URLRequest("library.swf"); 16 ldr.load(urlReq); 17 ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete); 18 } 19 20 private function onComplete(event:Event):void { 21 var loaderInfo:LoaderInfo = (event.target as LoaderInfo); 22 loaded[url]=loaderInfo.loader.contentLoaderInfo.applicationDomain; 23 var classReference:Class = ApplicationDomain(loaded[url]).getDefinition("com.test.Circle") as Class; 24 var ss:Sprite = new classReference(); 25 ss.x = 200; 26 ss.y = 200; 27 ui.addChild(ss); 28 } 29 30 ]]> 31 </fx:Script> 32 <mx:UIComponent id="ui"/> 33 </s:WindowedApplication>
项目跑起来,会看到一个红色的圆,这就是在库项目中自定义的一个简单组件.
在项目应用中,可以形成一个相对固定的组件库,形成一个swf,然后经过一定的封装,就可以达到和java反射一模一样的效果了。