質問

現在、標準のAS3アプリケーションとAIRアプリケーションの両方から外部SWFファイルをロードする実験を行っています。 AIRアプリケーションは、Flash Playerで実行される標準のSWFと同じようには動作しないようです。

ドキュメントによると、 LoaderContext applicationDomain プロパティは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

ドキュメントによると、最初の出力(AIRアプリケーションではなく、Flash PlayerでSWFを使用)が正しい出力です。また、このスニペットで遊んで、アプリケーションドメインを他の可能な構成( new ApplicationDomain(null)、または ApplicationDomain.currentDomain など)に変更すると、ドキュメントに記載されているとおりのことが行われますSWF。ただし、AIRアプリケーションの出力は変更されません。

AIRが単にローダーコンテキストに渡されたアプリケーションドメインを無視している理由は何ですか?この特定の問題に関するドキュメントはありますか?

ありがとうございます。

役に立ちましたか?

解決

了解。

この問題は、AIRアプリケーション内の SecurityDomain システムの動作が異なるために発生しました。 SWFファイルがAIRアプリケーション内にロードされると、常に異なるサンドボックスに依存します。したがって、AIRはこのSWFの新しい SecurityDomain を作成します。

SecurityDomain は1つ以上の ApplicationDomain のグループであるため、この動作により、新しい ApplicationDomain (新しい SecurityDomain )、指定されたもの(「メイン」 SecurityDomain に属する)を無視します。

URLLoader を使用する回避策があります。バイトコードから( Loader.loadBytes を使用して)ロードすると、SWFは同じ SecurityDomain 内にロードされます。安全でない可能性があるため、 allowLoadBytesCodeExecution をtrueに設定する必要があるのはこのためです。したがって、最初に URLLoader を使用してSWFを間接的にロードし、次に 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"));
        }
    }
}

これがお役に立てば幸いです。

他のヒント

それは良いものです、ありがとう:)

もう1つの詳細: allowLoadBytesCodeExecution はレガシープロパティになり、AIR 1.0で定義されました。 AIR 2.0では、代わりに allowCodeImport を使用します。

ciao、 PG

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top