2009-03-03 36 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