根据documentation,LoaderContext的applicationDomain属性也可以在AIR应用程序中使用,但它似乎无法正常工作.
我有以下代码:
package { import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; public class Invoker extends Sprite { private var _ldr : Loader; public function Invoker() { _ldr = new Loader(); _ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,onChildOneComplete); var ldrC : LoaderContext = new LoaderContext(false,new ApplicationDomain(ApplicationDomain.currentDomain) ); _ldr.load(new URLRequest("otherSwf.swf"),ldrC); } private function onChildOneComplete(e : Event) : void { var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain; var inad : ApplicationDomain = ApplicationDomain.currentDomain; trace("Child One parentDomain : " + c1ad.parentDomain); trace("Invoker parentDomain : " + inad.parentDomain); trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker")); trace("Invoker has Invoker : " + inad.hasDefinition("Invoker")); } } }
将此代码编译为SWF文件并使用Flash Player启动它会执行此输出,这似乎是正确的:
Child One parentDomain : [object ApplicationDomain] Invoker parentDomain : null Child One has Invoker : true Invoker has Invoker : true
Child One parentDomain : null Invoker parentDomain : null Child One has Invoker : false Invoker has Invoker : true
根据文档,第一个输出(使用SWF与Flash Player,而不是AIR应用程序)是正确的.此外,使用此代码段并将应用程序域更改为其他可能的配置(如新的ApplicationDomain(null)或ApplicationDomain.currentDomain)确实可以说明文档对SWF所说的内容,但不会更改AIR应用程序的输出.
任何线索为什么AIR只是忽略传递给加载器上下文的应用程序域?有关此特定问题的任何文档?
非常感谢你.
解决方法
该问题是由AIR应用程序中的SecurityDomain系统中的不同行为引起的.在AIR应用程序中加载SWF文件时,它始终依赖于不同的沙箱.因此,AIR为此SWF创建一个新的SecurityDomain.
由于SecurityDomain是一个或多个ApplicationDomain的组,因此此行为强制创建新的ApplicationDomain(在新的SecurityDomain中),忽略指定的(属于’main’SecurityDomain).
使用URLLoader有一种解决方法.从字节码加载(使用Loader.loadBytes)时,SWF将加载到同一个SecurityDomain中.这就是为什么你必须将allowLoadBytesCodeExecution设置为true,因为它可能是不安全的.因此,首先通过URLLoader,然后使用Loader.loadBytes间接加载SWF,解决了这个问题.
这是片段:
package { import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.net.URLLoader; import flash.net.URLLoaderDataFormat; import flash.net.URLRequest; import flash.system.ApplicationDomain; import flash.system.LoaderContext; import flash.utils.ByteArray; public class Invoker extends Sprite { public function Invoker() { var uldr : URLLoader = new URLLoader(); uldr.dataFormat = URLLoaderDataFormat.BINARY; uldr.addEventListener(Event.COMPLETE,onBytesComplete); uldr.load(new URLRequest("otherSwf.swf")); } private function onBytesComplete(e : Event) : void { var bytes : ByteArray = (e.target as URLLoader).data; var ldr : Loader = new Loader(); ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,onChildComplete); var ldrC : LoaderContext = new LoaderContext(); // This property was for AIR 1.0. //ldrC.allowLoadBytesCodeExecution = true; // Since AIR 2.0,it's allowCodeImport. ldrC.allowCodeImport = true; ldr.loadBytes(bytes,ldrC); } private function onChildComplete(e : Event) : void { var c1ad : ApplicationDomain = (e.target as LoaderInfo).applicationDomain; var inad : ApplicationDomain = ApplicationDomain.currentDomain; trace("Child One parentDomain : " + c1ad.parentDomain); trace("Invoker parentDomain : " + inad.parentDomain); trace("Child One has Invoker : " + c1ad.hasDefinition("Invoker")); trace("Invoker has Invoker : " + inad.hasDefinition("Invoker")); } } }
希望这可以帮助.