Frage

Ich experimentiere derzeit mit Laden externe SWF-Dateien sowohl aus einer Standard-AS3-Anwendung und eine AIR-Anwendung. Es scheint, dass die AIR-Anwendung nicht auf die gleiche Weise ausgeführt wirkt ein Standard-SWF durch den Flash-Player der Fall ist.

Nach der Dokumentation , die applicationDomain Eigenschaft LoaderContext ist auch in einer AIR-Anwendung brauchbar, aber es scheint nur zu nicht funktioniert.

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

Mit diesem Code als SWF-Datei kompiliert und mit dem Flash Player macht diese Ausgabe startet, das richtig erscheint:

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 hat eine andere Ausgabe:

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

Nach der Dokumentation, die erste Ausgabe (eine SWF-Datei mit Flash Player verwenden und nicht einer AIR-Anwendung) ist die richtige. Auch das Spiel mit diesem Code-Schnipsel und das Ändern der Anwendungsdomäne zu anderen möglichen Konfigurationen (wie new ApplicationDomain(null) oder ApplicationDomain.currentDomain) tut exaclty, was die Dokumentation mit dem SWF sagt, aber nicht den Ausgang der AIR-Anwendung geändert werden.

Jede Ahnung, warum AIR einfach ist die Anwendungsdomäne an den Loader Kontext übergeben zu ignorieren? Jede Dokumentation zu diesem speziellen Thema?

Vielen Dank.

War es hilfreich?

Lösung

Haben Sie es.

wurde das Problem durch ein anderes Verhalten im SecurityDomain System innerhalb einer AIR-Anwendung verursacht. Wenn eine SWF-Datei in einer AIR-Anwendung geladen wird, es hängt immer zu einer anderen Sandbox. Somit schafft AIR ein neues SecurityDomain für diese SWF-Datei.

Da eine SecurityDomain eine Gruppe von einem oder mehreren ApplicationDomains ist, gezwungen, dieses Verhalten die Schaffung eines neuen ApplicationDomain (innerhalb des neuen SecurityDomain), die angegebene man ignorieren (die dem ‚Haupt‘ SecurityDomain gehören).

Es gibt eine Abhilfe mit URLLoader. Wenn von Bytecode (mit Loader.loadBytes) geladen wird, wird ein SWF innerhalb derselben SecurityDomain geladen. Aus diesem Grund müssen Sie die allowLoadBytesCodeExecution auf true setzen, da es unsicher sein kann. So Laden den SWF indirekt, jedoch zuerst ein URLLoader und dann mit Loader.loadBytes, löst dieses Problem.

Hier ist das Snippet:

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

Hope, das hilft.

Andere Tipps

Das ist ein guter, thanx:)

Nur noch ein Detail: allowLoadBytesCodeExecution ein Erbe Eigenschaft wird jetzt, es wurde in AIR 1.0 definiert. Von AIR 2.0 auf den Einsatz allowCodeImport statt.

ciao, PG

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top