- 浏览: 54464 次
- 性别:
- 来自: 天津
最近访客 更多访客>>
最新评论
-
shuiyunbing:
单元格样式怎么处理?
将flex页面数据导出到excel -
gaoyide:
啥破玩意!!
FLEX alive pdf 打印pdf -
zhong_pro:
关于博主的问题点,做如下修改就可以达到不需要属性isSelec ...
Flex 4通过重写DataGridColumn和CheckBox类给DataGrid添加选择列-CheckBoxColumn -
zhenxingzzx:
看不到附件的 !!
Adobe AIR右键菜单和系统托盘(Tray)功能以及实现方法 -
pangxin12345:
dingdingdingdingding
Adobe AIR右键菜单和系统托盘(Tray)功能以及实现方法
Flex 反射简介
在很多时候反射为程序的动态性提供了一种可能,从而成了在程序开发设计中必不可少的一种技术。了解 Java 的人都知道,Java 具有反射功能,可以根据类名生成类的实例,获取类的相关方法名称、调用方法等。大名鼎鼎的 Spring 框架,其依赖注入的基础也是建立在反射的基础之上。
同样 Flex 中也提供了类似的反射功能,但由于语言的不同,Flex 代码一般情况下是被编译后形成 swf 文件被加载到浏览器中运行。而且 Flex 中有诸如 Module,RSL(Runtime Shared Library) 等 Java 所没有的特殊技术,所以在 Flex 开发中反射的情况比 Java 更加复杂。
本文中将全面的讨论普通情况,以及使用 RSL 和 Module 技术情况下的 Flex 反射问题。
回页首
基本的类的反射
基本的情况下,我们将不使用任何 RSL 和 Module 的技术。为了进行这类反射实验,我们首先创建一个 Flex 的 Web 项目 MainApp,在该项目中我们定义一个接口类 IPerson, 其两个实现类分别为 PersonImplA 和 PersonImplB。我们在程序中希望根据不同的条件分别调用不同的实现类去进行操作。这时我们就可以利用 Flex 的反射来实现。接口类和实现类的示例代码如下:
清单 1:IPerson.as
package com.test
{
public
interface IPerson
{
function sayHello():String;
}
}
清单 2:PersonImplA.as
package com.test
{
public class PersonImplA implements IPerson
{
public function PersonImplA()
{
}
public function sayHello():String
{
return "This is PersonImplA!";
}
}
}
清单 3:PersonImplB.as
package com.test
{
public class PersonImplB implements IPerson
{
public function PersonImplB()
{
}
public function sayHello():String
{
return "This is PersonImplB!";
}
}
}
下面在我们的主程序中,我们放置一个下拉列表和一个按钮。我们在点击按钮的时候,将根据下拉列表中选择的值进行反射。选择相应的实现类去调用其 sayHello() 方法。代码如下:
清单 4:MainApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import com.test.*;
[Bindable]
private var str:String;
[Bindable]
private var classArray:Array =
[{label:"PersonImplA", data:"com.test.PersonImplA"},
{label:"PersonImplB", data:"com.test.PersonImplB"}];
private
var classInstance:IPerson;
// 尝试一下去掉下面两个变量的定义再次运行看看程序会不会有异常?
private var pa:PersonImplA;
private var pb:PersonImplB;
private function sayHello():void
{
var classRefrence:Class = getDefinitionByName(
classCombo.selectedItem.data.toString()) as Class;
var classInstance:IPerson = new classRefrence() as IPerson;
str = classInstance.sayHello();
}
]]>
</mx:Script>
<mx:HBox>
<mx:Text text="请选择 Class"/>
<mx:ComboBox id="classCombo" dataProvider="{classArray}" change="str='';">
</mx:ComboBox>
<mx:Button label="运行 sayHello()" click="sayHello()"/>
<mx:Text text="{str}"/>
</mx:HBox>
</mx:Application>
从图 1 的程序运行结果我们可以看出,当我们选择不同的实现类类名的时候,程序会根据我们的选择反射出相应实现类的实例,进而输出不同的结果。
图 1:反射运行效果图
图 1:反射运行效果图
值得注意的是,程序中定义了两个变量 pa 和 pb,但实际上并没有使用到它们。如果我们按照程序中的注释,将变量 pa 和 pb 的定义去掉然后运行,我们将会看到程序会有如图 2 的反射异常产生。
图 2:反射异常
图 2:反射异常
原来 Flex 将 MainApp.mxml 编译成 MainApp.swf 的时候,默认情况下不会将所有 import 的类都编译到 MainApp.swf 中去,只有真正使用到的类才会被编译进去。所以当我们将变量 pa 和 pb 的定义注释掉以后,com.test.PersonImplA 和 com.test.PersonImplB 都不会被编译到 MainApp.swf 中去。此时 MainApp.swf 被浏览器 load 到客户端运行的时候,由于找不到相应的类定义所以就产生了反射异常。有些读者在遇到这类问题的时候常常会抱怨 Flex,实际上 Flex 这样的做法也是为了减小生成的 swf 文件的大小。另外,如果不是使用 FlexBuilder 自动编译生成的 swf 文件,而是自己通过 Ant 脚本来编译的话,则可以通过向 Flex 的 Ant compc 任务增加 include-sources 参数来指定将哪些类编译到 swc 和 swf 中去。关于 Flex 的 Ant 脚本编译问题不是本文重点,不再赘述。有兴趣的读者可以查阅 Flex 的 Doc。
在使用 Flex 开发应用程序的时候,我们通常会使用 RSL 技术在多个应用程序间共享库,从而实现减少 Flex 应用程序大小的目的。那么在使用 RSL 的情况下,反射又会是什么情况呢?
回页首
RSL 与反射
为了实验在 RSL 的条件下的反射问题,接下来需要建立一个 Flex 的 library 项目 RSLApp,并且设置好刚刚建立的主项目 MainApp 和 RSLApp 之间的依赖关系。具体的设置可以通过 下载 我们的源代码来进行研究。在 RSLApp 项目中,与 PersonImplA 和 PersonImplB 类似,我们建立一个新类 PersonImplC,其代码如下:
清单 5:PersonImplC.as
package com.rsl
{
// 因为在 RSL Project 中 , 并不能 import 主应用中的类,所以我们无法实现 IPerson 接口
public class PersonImplC
{
public function PersonImplC()
{
}
public function sayHello():String
{
return "This is RSL PersonImplC!";
}
}
}
这里需要注意的是由于在 RSL 项目中无法 import MainApp 项目中的类,所以无法实现 IPerson 接口,我们只是依然添加一个 sayHello() 方法而已。做了这些准备工作后,开始我们的第一个实验。
从主应用中反射 RSL 中的类
在这个实验中,我们将从 MainApp.mxml 中反射 com.rsl. PersonImplC 。因为 PersonImplC 并没有实现 IPerson 接口,所以我们要对 MainApp.mxml 中有关反射的 sayHello() 方法进行相应的修改。如清单 6 所示。
清单 6:修改后的 sayHello() 方法
private function sayHello():void
{
var classRefrence:Class = getDefinitionByName(
classCombo.selectedItem.data.toString()) as Class;
// 因为 com.rsl.PersonImplC 和 com.rsl.PersonImplC 并没有实现 IPerson 接口
// var classInstance:IPerson = new classRefrence() as IPerson;
var classInstance:Object = new classRefrence() as Object;
str = classInstance.sayHello();
}
这时运行 MainApp.mxml,利用 FireFox 的 HttpFox 插件可以看到,程序在第一次被浏览器载入后会将 RSLApp.swf 载入并缓存起来。从图 3 可以看出从 MainApp 可以成功反射 RSL 中的类 com.rsl.PersonImplC
图 3:主应用中反射 RSL 中的类
图 3:主应用中反射 RSL 中的类
发现了电能生磁以后,法拉第用了十年的时间才发现了磁也能生电。我们从主应用中成功的反射 RSL 中的类以后,接下来我们是不是也要进行一个反向实验呢?没错,我们下面要从 RSL 中反射主应用中的类。
从 RSL 反射主应用中的类
为了进行这个反向实验,我们在 RSLApp 项目中创建一个新类 com.rsl.PersonImplD, 在 PersonImplD 类的 sayHello() 方法中,我们反射 MainApp 项目中的 com.test.PersonImplA 类。如清单 7 所示。
清单 7:com.rsl.PersonImplD
package com.rsl
{
import flash.utils.getDefinitionByName;
// 因为在 RSL Project 中 , 并不能 import 主应用中的类,所以我们无法实现 IPerson 接口
public class PersonImplD
{
public function PersonImplD()
{
}
public function sayHello():String
{
var classRefrence:Class = getDefinitionByName(
"com.test.PersonImplA") as Class;
var classInstance:Object = new classRefrence() as Object;
return "从 RSL 中反射 MainApp 中的类 " + classInstance.sayHello();
}
}
}
同样,运行我们的主应用程序 MainApp, 我们可以看到从 RSL 中也可以成功反射主应用中的类。
图 4:从 RSL 中反射主应用中的类
图 4:从 RSL 中反射主应用中的类
刚才我们进行了从主应用反射 RSL 中类,以及从 RSL 反射主应用中类两组实验。关于 RSL 的反射,还有更多的主题。有兴趣的读者可以自己尝试一下在两个 RSL 项目之间互相反射。以及再建立一个主应用 MainApp2, 让 MainApp 和 MainApp2 两个主应用共享同一个 RSLApp, 尝试一下从 MainApp2 中是否可以成功反射由 MainApp 载入的 RSLApp 中的类。本文不再赘述。
到此为止,我们似乎可以得到一个结论。只要被反射的类被编译到 swf 中,并且被浏览器加载到客户端 FlashPlayer 中,我们就可以任意的进行反射。但是事实上到底真的如此么?还可以让我们来一起看一看反射在 Module 中的情况。
回页首
Module 反射
和 RSL 类似,我们在进行 Flex 开发的时候经常会将应用程序分成多个 Module 来减少应用程序的大小。那么我们刚才得到的结论在存在 Module 的情况下还能成立么?
为了进行验证,我们类似的创建一个新类 com.module.PersonImplE,我们此次不再分两次来分别验证从主应用程序反射 Module 中的类,以及从 Module 中反射主应用程序的类。所以我们在 PersonImplE 的 sayHello() 方法中去反射主应用中的 com.test.PersonImplA 类。
清单 8:com.module.PersonImplE
package com.module
{
import flash.utils.getDefinitionByName;
public class PersonImplE
{
public function PersonImplE()
{
}
public function sayHello():String
{
var classRefrence:Class = getDefinitionByName(
"com.test.PersonImplA") as Class;
var classInstance:Object = new classRefrence() as Object;
return "从 Module 中反射 MainApp 中的类 " + classInstance.sayHello();
}
}
}
并且我们新建一个 SampleModule,我们在 SampleModule 中定义了一个 PersonImplE 类型的变量就是为了把 com.module.PersonImplE 编译到 SampleModule.swf 中去。
清单 8:SampleModule.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
// 定义这个变量是为了让 com.module.PersonImplE 编译到 SampleModule 中
private var pe:PersonImplE;
]]>
</mx:Script>
</mx:Module>
现在我们修改 MainApp.mxml,在 MainApp 在初始化的时候载入 SampleModule.swf
代码如清单 9 所示:
清单 9:SampleModule.mxml
private function loadModule():void
{
assetModule = ModuleManager.getModule("com/module/SampleModule.swf");
// 将下面这行代码换成 assetModule.load(); 看看反射时候还会成功?
assetModule.load(ApplicationDomain.currentDomain);
}
运行 MainApp.mxml,我们可以看到主应用程序成功的反射了 PersonImplE,并调用了它的 sayHello() 方法。在 PersonImplE 的 sayHello() 方法中,PersonImplE 又反向反射了主应用程序中的 com.test.PersonImplA 类。从而通过这个实验我们成功进行了双向反射验证。
图 5:主应用和 Module 之间的双向反射
图 5:主应用和 Module 之间的双向反射
到此为止,似乎一切顺利。和我们在 RSL 部分得出的结论没有任何差别。别急,注意清单 9 中的注释,将 assetModule.load(ApplicationDomain.currentDomain); 替换成 assetModule.load(); 再运行一下程序,看看是不是得到了令人厌恶的反射异常?别着急,讨厌的还不仅如此,如果你不是使用 ModuleManager,而是使用例如清单 10 所示的几种方式,看看会有什么不同的测试结果?
清单 10:用不同的方式载入 Module
private function loadModule():void
{
// 第一种方式 : 用 ModuleManager 来载入 Module
assetModule = ModuleManager.getModule("com/module/SampleModule.swf");
// 将下面这行代码换成 assetModule.load(); 看看反射时候还会成功?
assetModule.load(ApplicationDomain.currentDomain);
// 第二种方式 : 用 ModuleLoader 试试看能否反射成功?
//moduleLoader.applicationDomain = ApplicationDomain.currentDomain;
//moduleLoader.loadModule("com/module/SampleModule.swf");
// 第三种方式 : 设置 applicationDomain 和 load 的顺序颠倒一下看看反射是否还能成功?
//moduleLoader.loadModule("com/module/SampleModule.swf");
//moduleLoader.applicationDomain = ApplicationDomain.currentDomain;
}
有兴趣的读者可以深入的研究 Module 的载入域和反射结果的关系,还可以像我们讨论 RSL 反射的部分一样,对不同 Module 之间的反射进行实验。本文不再赘述。
结束语
相对开发过程中讨厌的反射异常,也许坐下来对 Flex 的反射做一次全面的总结整理感觉可能会更好。本文总结了 Flex 在很多种情况下的反射情况,限于篇幅没有给出全部的答案,有兴趣的读者可以对全部场景都加以实验并作出全面整理。
在很多时候反射为程序的动态性提供了一种可能,从而成了在程序开发设计中必不可少的一种技术。了解 Java 的人都知道,Java 具有反射功能,可以根据类名生成类的实例,获取类的相关方法名称、调用方法等。大名鼎鼎的 Spring 框架,其依赖注入的基础也是建立在反射的基础之上。
同样 Flex 中也提供了类似的反射功能,但由于语言的不同,Flex 代码一般情况下是被编译后形成 swf 文件被加载到浏览器中运行。而且 Flex 中有诸如 Module,RSL(Runtime Shared Library) 等 Java 所没有的特殊技术,所以在 Flex 开发中反射的情况比 Java 更加复杂。
本文中将全面的讨论普通情况,以及使用 RSL 和 Module 技术情况下的 Flex 反射问题。
回页首
基本的类的反射
基本的情况下,我们将不使用任何 RSL 和 Module 的技术。为了进行这类反射实验,我们首先创建一个 Flex 的 Web 项目 MainApp,在该项目中我们定义一个接口类 IPerson, 其两个实现类分别为 PersonImplA 和 PersonImplB。我们在程序中希望根据不同的条件分别调用不同的实现类去进行操作。这时我们就可以利用 Flex 的反射来实现。接口类和实现类的示例代码如下:
清单 1:IPerson.as
package com.test
{
public
interface IPerson
{
function sayHello():String;
}
}
清单 2:PersonImplA.as
package com.test
{
public class PersonImplA implements IPerson
{
public function PersonImplA()
{
}
public function sayHello():String
{
return "This is PersonImplA!";
}
}
}
清单 3:PersonImplB.as
package com.test
{
public class PersonImplB implements IPerson
{
public function PersonImplB()
{
}
public function sayHello():String
{
return "This is PersonImplB!";
}
}
}
下面在我们的主程序中,我们放置一个下拉列表和一个按钮。我们在点击按钮的时候,将根据下拉列表中选择的值进行反射。选择相应的实现类去调用其 sayHello() 方法。代码如下:
清单 4:MainApp.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
<mx:Script>
<![CDATA[
import com.test.*;
[Bindable]
private var str:String;
[Bindable]
private var classArray:Array =
[{label:"PersonImplA", data:"com.test.PersonImplA"},
{label:"PersonImplB", data:"com.test.PersonImplB"}];
private
var classInstance:IPerson;
// 尝试一下去掉下面两个变量的定义再次运行看看程序会不会有异常?
private var pa:PersonImplA;
private var pb:PersonImplB;
private function sayHello():void
{
var classRefrence:Class = getDefinitionByName(
classCombo.selectedItem.data.toString()) as Class;
var classInstance:IPerson = new classRefrence() as IPerson;
str = classInstance.sayHello();
}
]]>
</mx:Script>
<mx:HBox>
<mx:Text text="请选择 Class"/>
<mx:ComboBox id="classCombo" dataProvider="{classArray}" change="str='';">
</mx:ComboBox>
<mx:Button label="运行 sayHello()" click="sayHello()"/>
<mx:Text text="{str}"/>
</mx:HBox>
</mx:Application>
从图 1 的程序运行结果我们可以看出,当我们选择不同的实现类类名的时候,程序会根据我们的选择反射出相应实现类的实例,进而输出不同的结果。
图 1:反射运行效果图
图 1:反射运行效果图
值得注意的是,程序中定义了两个变量 pa 和 pb,但实际上并没有使用到它们。如果我们按照程序中的注释,将变量 pa 和 pb 的定义去掉然后运行,我们将会看到程序会有如图 2 的反射异常产生。
图 2:反射异常
图 2:反射异常
原来 Flex 将 MainApp.mxml 编译成 MainApp.swf 的时候,默认情况下不会将所有 import 的类都编译到 MainApp.swf 中去,只有真正使用到的类才会被编译进去。所以当我们将变量 pa 和 pb 的定义注释掉以后,com.test.PersonImplA 和 com.test.PersonImplB 都不会被编译到 MainApp.swf 中去。此时 MainApp.swf 被浏览器 load 到客户端运行的时候,由于找不到相应的类定义所以就产生了反射异常。有些读者在遇到这类问题的时候常常会抱怨 Flex,实际上 Flex 这样的做法也是为了减小生成的 swf 文件的大小。另外,如果不是使用 FlexBuilder 自动编译生成的 swf 文件,而是自己通过 Ant 脚本来编译的话,则可以通过向 Flex 的 Ant compc 任务增加 include-sources 参数来指定将哪些类编译到 swc 和 swf 中去。关于 Flex 的 Ant 脚本编译问题不是本文重点,不再赘述。有兴趣的读者可以查阅 Flex 的 Doc。
在使用 Flex 开发应用程序的时候,我们通常会使用 RSL 技术在多个应用程序间共享库,从而实现减少 Flex 应用程序大小的目的。那么在使用 RSL 的情况下,反射又会是什么情况呢?
回页首
RSL 与反射
为了实验在 RSL 的条件下的反射问题,接下来需要建立一个 Flex 的 library 项目 RSLApp,并且设置好刚刚建立的主项目 MainApp 和 RSLApp 之间的依赖关系。具体的设置可以通过 下载 我们的源代码来进行研究。在 RSLApp 项目中,与 PersonImplA 和 PersonImplB 类似,我们建立一个新类 PersonImplC,其代码如下:
清单 5:PersonImplC.as
package com.rsl
{
// 因为在 RSL Project 中 , 并不能 import 主应用中的类,所以我们无法实现 IPerson 接口
public class PersonImplC
{
public function PersonImplC()
{
}
public function sayHello():String
{
return "This is RSL PersonImplC!";
}
}
}
这里需要注意的是由于在 RSL 项目中无法 import MainApp 项目中的类,所以无法实现 IPerson 接口,我们只是依然添加一个 sayHello() 方法而已。做了这些准备工作后,开始我们的第一个实验。
从主应用中反射 RSL 中的类
在这个实验中,我们将从 MainApp.mxml 中反射 com.rsl. PersonImplC 。因为 PersonImplC 并没有实现 IPerson 接口,所以我们要对 MainApp.mxml 中有关反射的 sayHello() 方法进行相应的修改。如清单 6 所示。
清单 6:修改后的 sayHello() 方法
private function sayHello():void
{
var classRefrence:Class = getDefinitionByName(
classCombo.selectedItem.data.toString()) as Class;
// 因为 com.rsl.PersonImplC 和 com.rsl.PersonImplC 并没有实现 IPerson 接口
// var classInstance:IPerson = new classRefrence() as IPerson;
var classInstance:Object = new classRefrence() as Object;
str = classInstance.sayHello();
}
这时运行 MainApp.mxml,利用 FireFox 的 HttpFox 插件可以看到,程序在第一次被浏览器载入后会将 RSLApp.swf 载入并缓存起来。从图 3 可以看出从 MainApp 可以成功反射 RSL 中的类 com.rsl.PersonImplC
图 3:主应用中反射 RSL 中的类
图 3:主应用中反射 RSL 中的类
发现了电能生磁以后,法拉第用了十年的时间才发现了磁也能生电。我们从主应用中成功的反射 RSL 中的类以后,接下来我们是不是也要进行一个反向实验呢?没错,我们下面要从 RSL 中反射主应用中的类。
从 RSL 反射主应用中的类
为了进行这个反向实验,我们在 RSLApp 项目中创建一个新类 com.rsl.PersonImplD, 在 PersonImplD 类的 sayHello() 方法中,我们反射 MainApp 项目中的 com.test.PersonImplA 类。如清单 7 所示。
清单 7:com.rsl.PersonImplD
package com.rsl
{
import flash.utils.getDefinitionByName;
// 因为在 RSL Project 中 , 并不能 import 主应用中的类,所以我们无法实现 IPerson 接口
public class PersonImplD
{
public function PersonImplD()
{
}
public function sayHello():String
{
var classRefrence:Class = getDefinitionByName(
"com.test.PersonImplA") as Class;
var classInstance:Object = new classRefrence() as Object;
return "从 RSL 中反射 MainApp 中的类 " + classInstance.sayHello();
}
}
}
同样,运行我们的主应用程序 MainApp, 我们可以看到从 RSL 中也可以成功反射主应用中的类。
图 4:从 RSL 中反射主应用中的类
图 4:从 RSL 中反射主应用中的类
刚才我们进行了从主应用反射 RSL 中类,以及从 RSL 反射主应用中类两组实验。关于 RSL 的反射,还有更多的主题。有兴趣的读者可以自己尝试一下在两个 RSL 项目之间互相反射。以及再建立一个主应用 MainApp2, 让 MainApp 和 MainApp2 两个主应用共享同一个 RSLApp, 尝试一下从 MainApp2 中是否可以成功反射由 MainApp 载入的 RSLApp 中的类。本文不再赘述。
到此为止,我们似乎可以得到一个结论。只要被反射的类被编译到 swf 中,并且被浏览器加载到客户端 FlashPlayer 中,我们就可以任意的进行反射。但是事实上到底真的如此么?还可以让我们来一起看一看反射在 Module 中的情况。
回页首
Module 反射
和 RSL 类似,我们在进行 Flex 开发的时候经常会将应用程序分成多个 Module 来减少应用程序的大小。那么我们刚才得到的结论在存在 Module 的情况下还能成立么?
为了进行验证,我们类似的创建一个新类 com.module.PersonImplE,我们此次不再分两次来分别验证从主应用程序反射 Module 中的类,以及从 Module 中反射主应用程序的类。所以我们在 PersonImplE 的 sayHello() 方法中去反射主应用中的 com.test.PersonImplA 类。
清单 8:com.module.PersonImplE
package com.module
{
import flash.utils.getDefinitionByName;
public class PersonImplE
{
public function PersonImplE()
{
}
public function sayHello():String
{
var classRefrence:Class = getDefinitionByName(
"com.test.PersonImplA") as Class;
var classInstance:Object = new classRefrence() as Object;
return "从 Module 中反射 MainApp 中的类 " + classInstance.sayHello();
}
}
}
并且我们新建一个 SampleModule,我们在 SampleModule 中定义了一个 PersonImplE 类型的变量就是为了把 com.module.PersonImplE 编译到 SampleModule.swf 中去。
清单 8:SampleModule.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute" width="400" height="300">
<mx:Script>
<![CDATA[
// 定义这个变量是为了让 com.module.PersonImplE 编译到 SampleModule 中
private var pe:PersonImplE;
]]>
</mx:Script>
</mx:Module>
现在我们修改 MainApp.mxml,在 MainApp 在初始化的时候载入 SampleModule.swf
代码如清单 9 所示:
清单 9:SampleModule.mxml
private function loadModule():void
{
assetModule = ModuleManager.getModule("com/module/SampleModule.swf");
// 将下面这行代码换成 assetModule.load(); 看看反射时候还会成功?
assetModule.load(ApplicationDomain.currentDomain);
}
运行 MainApp.mxml,我们可以看到主应用程序成功的反射了 PersonImplE,并调用了它的 sayHello() 方法。在 PersonImplE 的 sayHello() 方法中,PersonImplE 又反向反射了主应用程序中的 com.test.PersonImplA 类。从而通过这个实验我们成功进行了双向反射验证。
图 5:主应用和 Module 之间的双向反射
图 5:主应用和 Module 之间的双向反射
到此为止,似乎一切顺利。和我们在 RSL 部分得出的结论没有任何差别。别急,注意清单 9 中的注释,将 assetModule.load(ApplicationDomain.currentDomain); 替换成 assetModule.load(); 再运行一下程序,看看是不是得到了令人厌恶的反射异常?别着急,讨厌的还不仅如此,如果你不是使用 ModuleManager,而是使用例如清单 10 所示的几种方式,看看会有什么不同的测试结果?
清单 10:用不同的方式载入 Module
private function loadModule():void
{
// 第一种方式 : 用 ModuleManager 来载入 Module
assetModule = ModuleManager.getModule("com/module/SampleModule.swf");
// 将下面这行代码换成 assetModule.load(); 看看反射时候还会成功?
assetModule.load(ApplicationDomain.currentDomain);
// 第二种方式 : 用 ModuleLoader 试试看能否反射成功?
//moduleLoader.applicationDomain = ApplicationDomain.currentDomain;
//moduleLoader.loadModule("com/module/SampleModule.swf");
// 第三种方式 : 设置 applicationDomain 和 load 的顺序颠倒一下看看反射是否还能成功?
//moduleLoader.loadModule("com/module/SampleModule.swf");
//moduleLoader.applicationDomain = ApplicationDomain.currentDomain;
}
有兴趣的读者可以深入的研究 Module 的载入域和反射结果的关系,还可以像我们讨论 RSL 反射的部分一样,对不同 Module 之间的反射进行实验。本文不再赘述。
结束语
相对开发过程中讨厌的反射异常,也许坐下来对 Flex 的反射做一次全面的总结整理感觉可能会更好。本文总结了 Flex 在很多种情况下的反射情况,限于篇幅没有给出全部的答案,有兴趣的读者可以对全部场景都加以实验并作出全面整理。
- SourceCode.zip (44.9 KB)
- 下载次数: 1862
发表评论
-
[转]构建Flex应用的10大误区
2011-05-31 23:29 752原文地址:http://www.infoq ... -
转:flex滤镜:聚光灯效果、放大镜效果、缩放模糊效果、浮雕效果和水波效果
2011-05-30 21:30 1765可惜提供的源代码没有相应的libs包 1:聚光灯效果: 实 ... -
Air File类使用方法
2010-09-06 10:24 2287air file 系统中文件或目 ... -
Flex air修改外部xml文件
2010-09-06 09:35 2110AIR的文件操作不难,看完教程应该可以满足你对文件的所有基本操 ... -
air 读取服务器端文件
2010-09-03 13:44 1028import flash.events.Event; ... -
air下载文件
2010-09-02 10:43 834http://www.code-design.cn/blogd ... -
三维程序/游戏制作基本常识
2010-08-25 13:19 913Furry/DDM君: 很多flash3d初 ... -
FLEX的RIA应用程序中配置文件(*-app.xml)的说明
2010-06-22 16:53 885<?xml version="1.0" ... -
Adobe AIR右键菜单和系统托盘(Tray)功能以及实现方法
2010-05-31 17:21 2141AIR教程 Adobe AIR右键菜单和系统托盘(Tray ... -
Flash Bulider4注册码生成器
2010-05-18 11:03 1826Flash Builder 4正式版发布,很高兴还有简体中文 ... -
FLex视图模式与视图转换
2010-05-10 14:13 18303.2 视图模式与视图转换 3.2.1 视图模式 Fle ... -
FusionCharts中文乱码问题
2010-05-06 11:17 2889从 http://www.infosoftglobal.com ... -
Flex ShareObject简单应用
2010-04-26 17:47 1069[size=medium]Share object一般用来保存 ... -
FLEX问题总汇(1)
2010-04-23 15:17 879论坛一直有些问题有人重复的发帖,今天有空就做了点总结,希望和大 ... -
Flex 3 体验:AdvancedDataGrid的使用(第一部分)
2010-04-22 17:14 1415今天我们要说的是官方文档中用了整章介绍的AdvancedDat ... -
FLEX alive pdf 打印pdf
2010-04-22 10:33 1949FLEX alive pdf 打印pdf ,废话不多说了,代码 ... -
FLEX AIR 连接local SQL database
2010-04-22 10:19 1320FLEX AIR 连接本地LocalSQL实现增删改查,废话不 ... -
将flex页面数据导出到excel
2010-04-20 10:07 1632本例实现将flex中的数据 ... -
FLEX TEXTINPUT restrict(正则表达式,约束,限定)
2010-04-19 16:28 2087通常要对输入TextInput中 ... -
actionscript 中 如何控制数字精度(小数位数)
2010-04-16 16:58 1649很简单的一件事,但是如果不知道的话一样很麻烦。Number包里 ...
相关推荐
### Flex开发中的类反射技术详解 #### 引言 随着Flex技术在富互联网应用(RIA)领域的广泛应用,其独特的能力,如强大的图形处理能力和高效的数据处理机制,使其成为开发高性能Web应用的首选工具之一。Flex的灵活...
Flex特效编辑器是一款专为开发基于Adobe Flex技术的游戏而设计的强大工具。它简化了特效的创建过程,使得开发者能够更加高效地构建具有视觉冲击力的游戏体验。Flex是一种开放源码的框架,主要用于构建富互联网应用...
Flex反射是Adobe Flex框架中的一个重要特性,它允许在运行时检查和操作类、对象、方法、属性等元数据。在Flex编程中,反射提供了一种动态访问和操作应用程序组件的能力,即使在编译时未知其具体类型的情况下也可以...
8. **ReflexUtil**: 一个反射组件类,可用于动态操作和检查Flex对象。 9. **flex-object-handles**: 提供对象处理功能,通过XML配置实现对象的操作,但可能需要根据具体需求进行定制。 10. **CheckboxTree 和 ...
在开始交互之前,确保你已经安装了相应的开发环境,如Visual Studio(用于C#开发)和Flash Builder或IntelliJ IDEA(用于Flex开发)。还需要安装Adobe AIR SDK和.NET Framework。 2. **项目配置**: - **Flex项目...
4. **Spring**:SpringFactory类和反射机制,用于管理和实例化后端服务。 5. **业务层**:基于Spring框架,使用Hibernate处理数据库操作,实现业务逻辑。 6. **Flex Application, Module, Component**:Flex前端应用...
《Flex前端与Java服务端交互反射机制》 在软件开发中,前端与后端的交互是必不可少的一部分。本文主要探讨了使用Flex作为富互联网应用程序(RIA)前端与Java服务端进行交互的反射机制。Flex以其丰富的用户体验和...
- **面向对象编程**:类的定义、对象的创建、继承和多态性。 - **事件处理**:事件监听器、事件对象、事件流等。 - **高级主题**:异常处理、反射、泛型等。 - **游戏开发**:物理引擎的使用、碰撞检测、游戏循环等...
Flex是一款由Adobe公司开发的开源框架,主要用于构建富互联网应用程序(RIA)。在Flex中实现逼真的海洋效果是一项挑战,但通过巧妙的图形处理和动画技术,可以创建出令人惊叹的视觉体验。本教程将深入探讨如何在Flex...
这可以通过使用Flex的`flash.display.MovieClip`类来实现,它是AS3中用于处理动画和视频的核心类。 1. **嵌入SWF文件**: 要在Flex项目中嵌入SWF文件,我们需要使用`mx.controls.VideoDisplay`或`mx.core....
不过,针对 Java EE 开发的服务器端应用,可以通过集成 BlazeDS,充分利用 AMF 协议并能轻易与 Flex 前端交换数据,这种方式是 Java EE 应用程序集成 Flex 的首选。 BlazeDS 是 Adobe LifeCycle Data Services 的...
这些开源项目为开发者提供了丰富的组件库、工具和框架,帮助他们扩展Flex的功能,提高开发效率,并实现更复杂的应用场景。 1. Flexbox(http://flexbox.mrinalwadhwa.com/):这是一个由印度开发者建立的组件库,...
不过,针对 Java EE 开发的服务器端应用,可以通过集成 BlazeDS,充分利用 AMF 协议并能轻易与 Flex 前端交换数据,这种方式是 Java EE 应用程序集成 Flex 的首选。 BlazeDS 是 Adobe LifeCycle Data Services 的...
2.1Flex开发涉及的技术背景.................... 2.1.1Flex简介...................................... 2.1.2观察者模式................................. 2.1.3Flex的事件流机制...................... 2.1.4Flex...
8. **反射组件类reflexutil**: 为Flex开发提供反射功能的工具,可以帮助开发者在运行时检查和操作对象。 9. **flex-object-handles**: 一个对象处理组件,通过XML配置实现对Flex对象的操作。其功能强大,但可能需要...
Flex 3D支持多种光照类型(如点光源、平行光等)和材质属性(如颜色、镜面反射、环境贴图等),让3D模型更具真实感。 5. **动画和交互**:Flex 3D提供了丰富的动画控制机制,可以创建平滑的3D过渡效果。同时,用户...
Flex是由Adobe开发的一种基于ActionScript 3.0的开源框架,用于构建具有丰富用户界面的Flash应用程序。在Flex中实现3D效果,可以让开发者创建出更为生动和立体的交互体验。 在Flex中实现3D圆形隧道效果,需要掌握...
Flex是一款强大的开发工具,用于构建富互联网应用程序(RIA),它提供了丰富的组件库和强大的图形处理能力,使得开发者能够创建出具有高度交互性和动态效果的应用。 1. **SpotlightDemo**: 这个例子可能涉及到聚光...
Flex3D特效是一种基于Adobe Flex技术的三维图形和动画效果,它为开发人员提供了一种在Web上创建交互式、动态且引人入胜的用户体验的方式。Flex3D是Adobe Flex框架的一个扩展,允许开发者利用硬件加速的3D图形功能,...
Flex通信-Java服务端通信实例主要探讨的是在Web开发中,如何使用Adobe Flex与Java后端进行交互。Flex是一款强大的富互联网应用程序(RIA)开发工具,它可以创建动态、交互式的用户界面,而Java则通常作为服务器端的...