2009-03-03 15 views
8

Obecnie eksperymentuję z ładowaniem zewnętrznych plików SWF zarówno ze standardowej aplikacji AS3, jak i aplikacji AIR. Wygląda na to, że aplikacja AIR nie działa tak samo, jak standardowy plik SWF uruchamiany przez program Flash Player.LoaderContext i ApplicationDomain zmienia się w Adobe AIR?

Zgodnie z documentation właściwość z LoaderContext jest również użyteczna w aplikacji AIR, ale wygląda na to, że nie działa.

Mam następujący kod:

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

Kompilacja ten kod jako plik SWF i uruchomienia go z Flash robi to wyjście, które wydaje się w porządku:

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

Ale ten sam kod ponieważ aplikacja AIR ma inne wyjście:

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

Zgodnie z dokumentacją n, pierwsze wyjście (za pomocą SWF z Flash Player, a nie aplikacją AIR) jest właściwe. Ponadto obejście tego fragmentu kodu i zmiana domeny aplikacji na inne możliwe konfiguracje (na przykład new ApplicationDomain(null) lub ApplicationDomain.currentDomain) wykonuje dokładnie to, co dokumentacja mówi za pomocą pliku SWF, ale nie zmienia danych wyjściowych aplikacji AIR.

Dowolna wskazówka, dlaczego AIR po prostu ignoruje domenę aplikacji przekazaną do kontekstu modułu ładującego? Wszelka dokumentacja dotycząca tego konkretnego problemu?

Dziękuję bardzo.

Odpowiedz

14

Mam to.

Problem został spowodowany innym zachowaniem w systemie SecurityDomain w aplikacji AIR. Gdy plik SWF jest ładowany w aplikacji AIR, zawsze zależy od innego obszaru izolowanego. W związku z tym środowisko AIR tworzy nowy plik SecurityDomain dla tego pliku SWF.

Ponieważ SecurityDomain oznacza grupę o jednym lub kilku ApplicationDomain S, to zachowanie zmuszony do tworzenia nowego ApplicationDomain (w nowym SecurityDomain), ignorując wskazaną (które należą do „głównego” SecurityDomain).

Istnieje obejście z użyciem URLLoader. Po załadowaniu z kodu bajtowego (przy użyciu Loader.loadBytes) plik SWF jest ładowany w obrębie tego samego SecurityDomain. Dlatego musisz ustawić wartość allowLoadBytesCodeExecution jako prawdziwą, ponieważ może to być niebezpieczne. Dlatego załadowanie pliku SWF pośrednio, najpierw za pomocą URLLoader, a następnie za pomocą Loader.loadBytes, rozwiązuje ten problem.

Oto fragment:

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

Nadzieja to pomaga.

+0

Należy pamiętać, że trzeba będzie użyć [allowCodeImport] jak powiedział @pigiuz –

+0

Mam edytowane moją odpowiedź, aby wziąć to pod uwagę. Dzięki! – Tyn

1

że jest dobry, thanx :)

tylko jeden szczegół: allowLoadBytesCodeExecution jest obecnie własność dziedzictwo to zostało zdefiniowane w środowisku AIR 1.0. W środowisku AIR 2.0 zamiast tego użyj opcji allowCodeImport.

ciao, PG

Powiązane problemy