2009-03-03 7 views
8

Ich experimentiere gerade mit dem Laden externer SWF-Dateien von einer Standard-AS3-Anwendung und einer AIR-Anwendung. Es scheint, dass die AIR-Anwendung nicht so funktioniert, wie eine vom Flash Player ausgeführte Standard-SWF-Datei. Die applicationDomain Eigenschaft von LoaderContext ist in einer AIR-Anwendung auch verwendbar, aber es scheint nur nicht zu funktionieren.LoaderContext und ApplicationDomain ändert sich mit Adobe AIR?

Ich habe den folgenden Code:

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

diesen Code als SWF-Datei kompilieren und mit dem Flash Player startet macht diese Ausgabe, die rechts scheint:

Child One parentDomain : [object ApplicationDomain] 
Invoker parentDomain : null 
Child One has Invoker : true 
Invoker has Invoker : true 

Aber der gleiche Code wie eine AIR-Anwendung einen anderen Ausgang ausführt:

Gemäß der Documentatio n, die erste Ausgabe (mit einer SWF mit Flash Player und nicht eine AIR-Anwendung) ist die richtige. Wenn Sie mit diesem Snippet herumspielen und die Anwendungsdomäne für andere Konfigurationen ändern (z. B. new ApplicationDomain(null) oder ApplicationDomain.currentDomain), erfahren Sie genau, was in der Dokumentation mit der SWF-Datei gesagt wird, aber die Ausgabe der AIR-Anwendung ändert sich nicht.

Irgendwelche Anhaltspunkte, warum AIR einfach die Anwendungsdomäne ignoriert, die an den Loader-Kontext übergeben wird? Irgendwelche Unterlagen zu diesem speziellen Problem?

Vielen Dank.

Antwort

14

Verstanden.

Das Problem wurde durch ein anderes Verhalten im System SecurityDomain innerhalb einer AIR-Anwendung verursacht. Wenn eine SWF-Datei in eine AIR-Anwendung geladen wird, hängt sie immer von einer anderen Sandbox ab. Daher erstellt AIR eine neue SecurityDomain für diese SWF.

Da ein SecurityDomain ist eine Gruppe von einem oder mehreren ApplicationDomain s, dieses Verhalten gezwungen, die Schaffung eines neuen ApplicationDomain (innerhalb des neuen SecurityDomain), der einen spezifizierten ignoriert (der dem ‚Haupt‘ gehören SecurityDomain).

Es gibt eine Problemumgehung mit URLLoader. Beim Laden von Bytecode (unter Verwendung von Loader.loadBytes) wird eine SWF innerhalb desselben SecurityDomain geladen. Deshalb müssen Sie die allowLoadBytesCodeExecution auf true setzen, da es unsicher sein kann. Wenn Sie also die SWF-Datei indirekt laden, beheben Sie zuerst dieses Problem, indem Sie zuerst eine URLLoader und dann die Datei Loader.loadBytes aufrufen.

Hier ist der Code-Schnipsel:

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

Hoffnung, das hilft.

+0

Beachten Sie, dass [allowCodeImport] verwenden müssen, wie gesagt von @pigiuz –

+0

ich meine Antwort, dies zu berücksichtigen bearbeitet haben. Vielen Dank! – Tyn

1

, die ein gutes ist, thanx :)

Nur noch ein Detail: allowLoadBytesCodeExecution ist nun ein Erbe Eigenschaft, es wurde in AIR 1.0 definiert. Von AIR 2.0 bei Verwendung allowCodeImport stattdessen.

ciao, PG