2009-03-03 34 views
8

我目前正在试验从标准AS3应用程序和AIR应用程序中加载外部SWF文件。看起来,AIR应用程序的行为与Flash Player运行的标准SWF的行为方式不同。LoaderContext和ApplicationDomain随Adobe AIR改变了吗?

根据documentationLoaderContextapplicationDomain属性也可用于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 

但相同的代码作为AIR应用程序做不同的输出:

Child One parentDomain : null 
Invoker parentDomain : null 
Child One has Invoker : false 
Invoker has Invoker : true 

根据文档n,第一个输出(使用带有Flash Player的SWF,而不是AIR应用程序)是正确的。此外,仔细阅读此代码段并将应用程序域更改为其他可能的配置(如new ApplicationDomain(null)ApplicationDomain.currentDomain)确实可以显示文档对SWF所说的内容,但不会更改AIR应用程序的输出。

任何线索为什么AIR只是忽略传递给加载器上下文的应用程序域?有关这个特定问题的任何文档?

非常感谢。

回答

14

明白了。

该问题是由AIR应用程序中的SecurityDomain系统中的不同行为引起的。在AIR应用程序中加载SWF文件时,它始终依赖于不同的沙箱。因此,AIR会为此SWF创建一个新的SecurityDomain

由于SecurityDomain是一组一个或多个ApplicationDomain S,此行为被迫的创建的新ApplicationDomain(内新SecurityDomain),忽略了所指定的一个(其属于“主” SecurityDomain)。

有一种解决方法,使用URLLoader。当从字节码加载(使用Loader.loadBytes)时,SWF将在同一个SecurityDomain中加载。这就是为什么你必须将allowLoadBytesCodeExecution为真,因为它可能是不安全的。因此,间接加载SWF,首先通过URLLoader,然后与Loader.loadBytes解决此问题。

这里的片段:

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")); 
     } 
    } 
} 

希望这有助于。

+0

请注意,您将需要通过@pigiuz – 2013-03-07 08:18:49

1

这是一个很好的,感谢名单:)

只是一个细节:allowLoadBytesCodeExecution现在是一个传统的财产,它是在AIR 1.0的定义。取而代之的是从AIR 2.0开始使用allowCodeImport

的Ciao, PG