加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

flex – LoaderContext和ApplicationDomain是否随Adobe AIR发生

发布时间:2020-12-15 02:14:16 所属栏目:百科 来源:网络整理
导读:我目前正在尝试从标准AS3应用程序和AIR应用程序加载外部SWF文件.似乎AIR应用程序的行为与Flash Player运行的标准SWF的行为方式不同. 根据documentation,LoaderContext的applicationDomain属性也可以在AIR应用程序中使用,但它似乎无法正常工作. 我有以下代码
我目前正在尝试从标准AS3应用程序和AIR应用程序加载外部SWF文件.似乎AIR应用程序的行为与Flash Player运行的标准SWF的行为方式不同.

根据documentation,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

根据文档,第一个输出(使用SWF与Flash Player,而不是AIR应用程序)是正确的.此外,使用此代码段并将应用程序域更改为其他可能的配置(如新的ApplicationDomain(null)或ApplicationDomain.currentDomain)确实可以说明文档对SWF所说的内容,但不会更改AIR应用程序的输出.

任何线索为什么AIR只是忽略传递给加载器上下文的应用程序域?有关此特定问题的任何文档?

非常感谢你.

解决方法

得到它了.

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

由于SecurityDomain是一个或多个ApplicationDomain的组,因此此行为强制创建新的ApplicationDomain(在新的SecurityDomain中),忽略指定的(属于’main’SecurityDomain).

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

这是片段:

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

希望这可以帮助.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读