使用跨边界事件

使用跨边界事件

跨边界事件允许不同两个安全域中的swf以广播和侦听事件,因此不用使用导入加载的方式分配应用程序域。即载入swf模块后,不必导入到应用程序的安全域中,当也无需构建应用程序域的树级结构。保留各自的安全域后,主应用程序和模块之间无法访问到各自的应用程序域,因此不能使用getDefinition()方法获取任何定义。主应用程序和模块之间只能通过事件交换数据。实现事件广播侦听的对象时loaderInfo对象的sharedEvents属性,由于loaderInfo对象被加载器和加载的swf共享,因此sharedEvent引用的EventDispatcher对象也被两者共享。下图描述了这个过程:

安全域

 

主应用程序

loaderInfo对象

 

sharedEvents

安全域

 

模块文档类

 

 

 

 

 

 

 

这里的安全不同的安全域不是指AlplicationAdomain.Current 和其子域,以及新域!!

 

而是域名的域Domain !!  例如我们可以加载任何一个网站的图片或者swf !却不能访问里面的数据!除非你被作者授权了或者有策略文件!!假如  没授权 怎么实现两个不同 域Domain(不同地址url) 的 swf信息互访!!通过loaderInfo.sharedEvents实现!!!

 

前提两个swf都需要相应应的事件接口!dispatchEvent.......

 

 

 

 


举个跨边界事件交换数据的例子,创建一个发送事件的lib.fla,在帧上写如下代码:

//lib.fla

 

var timer:Timer=new Timer(50,100);

timer.addEventListener(TimerEvent.TIMER,onTimer);

timer.start();

 

function onTimer(event:TimerEvent):void

{

       loaderInfo.sharedEvents.dispatchEvent(event);

}

 

再创建一个主应用程序main.fla,在舞台上放置一个名为mc的影片剪辑,在帧上写如下代码:

 

var urlRequest:URLRequest=new URLRequest("libSwf.swf");

//main.fla

var loader:Loader=new Loader();

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,loaderComplete);

loader.load(urlRequest);

 

function loaderComplete(event:Event):void

{

       loader.contentLoaderInfo.sharedEvents.addEventListener(TimerEvent.TIMER,onTimer);

}

 

function onTimer(event:TimerEvent):void

{

       mc.x++;

}

可以发现侦听到sharedEvents广播的事件后,mc在缓缓向右移动。

跨边界事件是个实用技巧,即使两个swf互不信任,也不妨碍事件的广播侦听。载入到相同安全域或分配到任意应用程序域后也与跨边界事件无关。例如需要编写的模块swf能够在外部单独运行,所有的模块又能够被组织成一个大型应用程序。此时可以使用跨边界事件进行主应用程序和模块之间的通信。这种用跨边界实现的模块组合一般不使用RSL共享库,因为模块需要能单独运行。

如果模块不需要单独运行,就有使用RSL的可能性。使用跨边界事件的方式真的不能使用不同安全域中的定义吗?否也,我们不能使用getDefinition()方法获取定义,但是不能把定义传过来吗?答案是肯定的。我们可以自定义一个事件,使用事件属性把类的定义传过来。下面来实际演示一下,为了简化操作,我们还是使用flash为编写工具,以上面lib.flamain.fla为例,如下:

lib.fla新建一个类名为Mc的影片剪辑,使用ActionScript导出,导出类名也为Mc,在第一帧,舞台上不要放置任何影片。在帧上添加代码:

//lib.fla帧代码

loaderInfo.addEventListener(Event.COMPLETE,loadComplete);

 

function loadComplete(event:Event):void

{

       loaderInfo.sharedEvents.dispatchEvent(new ApplicationEvent(ApplicationEvent.DOMAIN_DEFINE,Mc));

}

 

//main.fla帧代码

var loader:Loader=new Loader();

loader.contentLoaderInfo.addEventListener(Event.COMPLETE,mcLoad);

loader.load(new URLRequest("http://localhost:8080/upload.swf"));

 

function mcLoad(event:Event):void

{

       loader.contentLoaderInfo.sharedEvents.addEventListener(ApplicationEvent.DOMAIN_DEFINE,getDomain);

}

 

 

function getDomain(event:Event):void

{

       txt.text=String((Object(event).defineClass));

}

 

//ApplicationEvent是自定义事件

package

{

       import flash.events.Event;

      

      

       public class ApplicationEvent extends Event

       {

              public static var DOMAIN_DEFINE="defineDomain";

              public var defineClass:Class;

 

              public function ApplicationEvent(type:String,defineClass:Class)

              {

                     super(type);

                     this.defineClass=defineClass;

              }

 

 

              public override function toString():String

              {

                     return formatToString("type","bubbles","cancelable","defineClass");

              }

 

 

              public override function clone():Event

              {

                     return new ApplicationEvent(ApplicationEvent.DOMAIN_DEFINE,defineClass);

              }

       }

}

lib.swf放到网络上,这里直接放到本机iis中。lib.fla注意更改沙箱类型为“只能访问网络”。测试lib.swf代码,发现输出了main.swf中的Mc定义。有个地方解释一下,在main.fla中使用Event为事件接受类型而不是ApplicationEvent,因为ApplicationEvent事件被看成两个不同命名空间中的类,这是应为lib.swfmain.swf是被单独编译的,ApplicationEvent被编译了两次。由于lib.swf中的定义在不同的安全域中,不能以共享方式获取,这里解决的办法是以基类Event作为类型,Event又不是一个动态类,所以转化为Object来引用applicationDomain属性。

不要幻想把lib.swf中的应用程序域传递过来,因为as3在使用applicationDomaingetDefinition()发放时发现applicationDomain不在安全域时会报错。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值