首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Adobe AIR改变了LoaderContext和ApplicationDomain?

Adobe AIR改变了LoaderContext和ApplicationDomain?
EN

Stack Overflow用户
提问于 2009-03-03 09:52:38
回答 2查看 7.9K关注 0票数 8

我目前正在尝试从一个标准的AS3应用程序和一个AIR应用程序加载外部SWF文件。AIR应用程序似乎与Flash播放器运行的标准SWF不同。

根据documentation的说法,LoaderContextapplicationDomain属性也可以在AIR应用程序中使用,但它似乎就是不起作用。

我有以下代码:

代码语言:javascript
复制
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启动它会产生以下输出,这似乎是正确的:

代码语言:javascript
复制
Child One parentDomain : [object ApplicationDomain]
Invoker parentDomain   : null
Child One has Invoker  : true
Invoker has Invoker    : true

但与AIR应用程序相同的代码会产生不同的输出:

代码语言:javascript
复制
Child One parentDomain : null
Invoker parentDomain   : null
Child One has Invoker  : false
Invoker has Invoker    : true

根据文档,第一个输出(使用带有Flash Player的SWF,而不是AIR应用程序)是正确的。此外,使用此代码片段并将应用程序域更改为其他可能的配置(如new ApplicationDomain(null)ApplicationDomain.currentDomain)确实符合文档对SWF的描述,但不会更改AIR应用程序的输出。

你知道为什么AIR简单地忽略传递给加载器上下文的应用程序域吗?有关于这个特定问题的文档吗?

非常感谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-03-03 10:37:12

明白了。

该问题是由AIR应用程序中SecurityDomain系统中的不同行为引起的。在AIR应用程序中加载SWF文件时,它始终依赖于不同的沙箱。因此,AIR为这个SWF创建了一个新的SecurityDomain

由于SecurityDomain是由一个或多个ApplicationDomain组成的组,因此此行为会强制创建新的ApplicationDomain (在新的SecurityDomain中),而忽略指定的SecurityDomain(属于“主”SecurityDomain)。

有一个使用URLLoader的解决方法。当从字节码加载时(使用Loader.loadBytes),SWF在同一SecurityDomain中加载。这就是为什么你必须将allowLoadBytesCodeExecution设为true,因为它可能是不安全的。因此,首先通过URLLoader间接加载SWF,然后使用Loader.loadBytes间接加载SWF,解决了这个问题。

下面是代码片段:

代码语言:javascript
复制
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"));
        }
    }
}

希望这能有所帮助。

票数 14
EN

Stack Overflow用户

发布于 2013-01-10 00:28:28

这是一个好问题,谢谢:)

再详细一点:allowLoadBytesCodeExecution现在是一个遗留属性,它是在AIR 1.0中定义的。在AIR 2.0中,请使用allowCodeImport

ciao,PG

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/605791

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档