`

使用 ApplicationDomain 类

阅读更多
本文版权归 博客园 黑夜丶残枫 所有,转载请详细标明原作者及出处,以示尊重!!
作者:黑夜丶残枫
原文:使用 ApplicationDomain 类


      要说应用程序域,就不得不说安全沙箱

      安全沙箱在帮助文档的解释是:

      客户端计算机可以从很多来源(如外部 Web 站点或本地文件系统)中获取单个 SWF 文件。当 SWF 文件及其它资源(例如共享对象、位图、声音、视频和数据文件)加载到 Flash Player 中时,      Flash Player 会根据这些文件和资源的来源单独地将其分配到安全沙箱中。

     从导入到安全域的 SWF 文件加载嵌入内容

     当加载 SWF 文件时,可以设置用于加载文件的 Loader 对象的 load() 方法中的 context 参数。此参数是一个 LoaderContext 对象。将此 LoaderContext 对象的 securityDomain 属性设置为 Security.currentDomain 时,Flash Player 将在被加载 SWF 文件所在的服务器上检查是否存在 URL 策略文件。如果存在策略文件,并且该文件向执行加载的 SWF 文件所在的域授予访问权限,则可以作为导入媒体加载 SWF 文件。这样,执行加载的文件可以获得对 SWF 文件的库中对象的访问权限。

     SWF 文件访问其它安全沙箱中被加载 SWF 文件的类的另一种方法是:使被加载的 SWF 文件调用 Security.allowDomain() 方法,以向执行调用的 SWF 文件所在的域授予访问权限。可以将对 Security.allowDomain() 方法的调用添加到被加载 SWF 文件的主类的构造函数方法中,然后使执行加载的 SWF 文件添加事件侦听器,以便响应由 Loader 对象的 contentLoaderInfo 属性调度的 init 事件。当调度此事件时,被加载的 SWF 文件已经调用构造函数方法中的 Security.allowDomain() 方法,因此被加载 SWF 文件中的类可用于执行加载的 SWF 文件。执行加载的 SWF 文件可以通过调用 Loader.contentLoaderInfo.applicationDomain.getDefinition() 从被加载的 SWF 文件中检索类。

      ApplicationDomain 类的用途是存储 ActionScript 3.0 定义表。SWF 文件中的所有代码被定义为存在于应用程序域中。可以使用应用程序域划分位于同一个安全域中的类。这允许同一个类存在多个定义,并且还允许子级重用父级定义。

      在使用 Loader 类 API 加载用 ActionScript 3.0 编写的外部 SWF 文件时,可以使用应用程序域。(请注意,在加载图像或用 ActionScript 1.0 或 ActionScript 2.0 编写的 SWF 文件时不能使用应用程序域。)包含在已加载类中的所有 ActionScript 3.0 定义都存储在应用程序域中。加载 SWF 文件时,通过将 LoaderContext 对象的 applicationDomain 参数设置为 ApplicationDomain.currentDomain,可以指定文件包含在 Loader 对象所在的相同应用程序域中。通过将加载的 SWF 文件放在同一个应用程序域中,可以直接访问它的类。如果加载的 SWF 文件包含嵌入的媒体(可通过其关联的类名称访问),或者您要访问加载的 SWF 文件的方法,则这种方式会很有用。

     使用应用程序域时,还要记住以下几点:

  • SWF 文件中的所有代码被定义为存在于应用程序域中。主应用程序在“当前域”中运行。“系统域”中包含所有应用程序域(包括当前域),也就是包含所有 Flash Player 类。

  • 所有应用程序域(除系统域外)都有关联的父域。主应用程序的应用程序域的父域是系统域。已加载的类仅在其父级中没有相关定义时才进行定义。不能用较新的定义覆盖已加载类的定义。

     下图显示了某个应用程序在单个域 (domain1.com) 中加载多个 SWF 文件的内容。根据加载内容的不同,可以使用不同的应用程序域。紧跟的文本说明用于为应用程序中的每个 SWF 文件设置适当应用程序域的逻辑。

 

img

 

       ApplicationDomain 是存放AS3定义(包括类、方法、接口等)的容器。使用Loader类加载swf时可以通过指定 ApplicationDomain 参数将swf加载到不同的域(Domain):

复制代码
var loader : Loader = new Loader();
var context : LoaderContext = new LoaderContext();
/* 加载到子域(模块) */
context.applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
/* 加载到同域(共享库) */
context.applicationDomain = ApplicationDomain.currentDomain;
/* 加载到新域(独立运行的程序或模块) */
context.applicationDomain = new ApplicationDomain();
loader.load(new URLRequest("loaded.swf"), context);
复制代码

 

 

      加载到子域(模块)
      类似于“继承”,子域可以直接获得父域所有的类定义,反之父域得不到子域的。和继承关系不同的是,如果子域中有和父域同名的类,子域定义会被忽略而使用父域的定义。
      加载到同域(运行时共享库)
      类似集合里的合并关系。被加载swf里的所有类定义被合并到当前域中可以直接使用。和加载到子域相同,和当前域同名的定义也会被忽略。
      加载到新域(独立运行的程序或模块)
swf载入指定域之前,先要检查该域及其父域中是否存在同名类,重复定义一概忽略。如果加载别人写的程序,或者使用旧版本的主程序加载新版本的模块,为避免类名冲突就要加载到新域独立运行以使用自己的类。
  模块加载到同域不是一样可以吗?为何要加载到子域呢?好处就在于,卸载一个加载到子域的模块时,只要确保清除所有到该模块的引用,模块的所有类定义将被垃圾回收(Garbage Collection)。
  

      有两种方式可以访问 ApplicationDomain :

      ApplicationDomain.currentDomain

      currentDomain是ApplicationDomain的静态变量,表示当前代码所在的域。该变量很奇特,在主程序里指向主域,在加载到子域的模块里则指向该模块所在的子域。虽然 ApplicationDomain 有个 parentDomain 属性,但子域已经自动获得了父域的类定义,所以通过 ApplicationDomain.currentDomain 就可以获取父域定义了——包括主程序和加载到主域的共享库。(注:系统域不可直接访问,主域和所有新域即系统域子域的parentDomain属性为null)
      LoaderInfo类的applicationDomain属性
此方式可以访问任何方式加载的swf的 ApplicationDomain。对于主程序来说,加载到同域的库定义已经存在于 ApplicationDomain.currentDomain ,而模块的类主程序一般用不到。所以这种方式个人不推荐使用。
  ApplicationDomain 的 hasDefinition() 方法判断某定义是否存在,getDefinition() 方法获取指定的定义。

 

     看上边的东东,是我在网上冬枣洗澡找出来的。能看多少就多少。感觉那种方式用的习惯好就用那个。下边,我贴一个自己写的代码。这个很简单,很明了,不拐弯抹角的。(只有两个flash,demo.swf,以及UI.swf,UI.swf里边仅仅就放了一个元件链接)

复制代码
package 
{
    import flash.display.Sprite;
    import flash.display.Loader;
    import flash.net.URLRequest;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.system.LoaderContext;
    import flash.system.ApplicationDomain;
    import flash.text.TextField;
    import flash.text.TextFormat;
    import UiDomain;

    [SWF(width = "720",height = "450",backgroundColor = "#0000ff")]
    public class Main extends Sprite
    {
        private var flower;
        private var way:String;
        private var loadContext:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);
        public function Main():void
        {
            var num=int(100*Math.random());
            if (num%3==0)
            {
                way = "1";
            }
            else if (num%3==1)
            {
                way = "2";
            }
            else if (num%3==2)
            {
                way = "3";
            }
            loadUi();
            showWay("以第"+way+"种方式");
        }

        private function loadUi()
        {
            var myLoader:Loader=new Loader();
            var myRequest:URLRequest=new URLRequest();
            myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,completeHandler);
            myRequest.url = "UI.swf";
            if (way=="1")
            {
                myLoader.load(myRequest,UiDomain.context);
            }
            else if(way=="2")
            {
                myLoader.load(myRequest,loadContext);
            }
            else if(way=="3")
            {
                myLoader.load(myRequest);
            }
            
        }
        private function completeHandler(e:Event)
        {
            showUI(e.currentTarget);
        }

        private function showUI(mc)
        {
            trace(mc);
            if (way=="1")
            {
                flower =new (UiDomain.getDefinition('Flower') as Class);
            }
            else if(way=="2")
            {
                //var mini:Class = getDefinition('Flower');
                var mini:Class=ApplicationDomain.currentDomain.getDefinition('Flower') as Class;
                flower = new mini();
            }
            else
            {
                //创建一个程序应用域
                var app:ApplicationDomain=mc.applicationDomain;
                //使用 getDefinition 获取UI中的链接名为Flower的类
                var mita:Class=app.getDefinition('Flower') as Class;
                flower=new mita();
            }
            flower.x = stage.stageWidth / 2  ;;//- flower.width / 2;
            flower.y = stage.stageHeight / 2  ;;//- flower.height / 2;
            addChild(flower);
            flower.buttonMode = true;
            flower.addEventListener(MouseEvent.CLICK,clickHandler);
        }

        private function clickHandler(e:MouseEvent)
        {
            e.target.rotation +=  15;
        }

        private function getDefinition(name:String)
        {
            if (name!=''||name!=null)
            {
                return ApplicationDomain.currentDomain.getDefinition(name) as Class;
            }
            return null;
        }




        private function showWay(str:String)
        {
            var txt:TextField=new TextField();
            var txtFormat:TextFormat=new TextFormat();
            txtFormat.size = 13;
            txtFormat.bold = true;
            txt.setTextFormat(txtFormat);
            txt.text = str;
            txt.x = 10;
            txt.y = 5;
            addChild(txt);
        }
    }

}
复制代码

 

 

复制代码
/*
*author: vini
*web: http://www.vini123.com;
*多处地方加载UI的话,可以利用这个封装类。
*/

package 
{
    import flash.system.ApplicationDomain;
    import flash.system.LoaderContext;
    public class UiDomain
    {
        //没写构造函数了。
        public static const loaderContext:LoaderContext = new LoaderContext(false,ApplicationDomain.currentDomain);

        public static function get context()
        {
            return loaderContext;
        }

        //根据元件链接名获取加载进来的元件
        public static function getDefinition(name:String)
        {
            if (((name != '') || name != null))
            {
                return ApplicationDomain.currentDomain.getDefinition(name) as Class;
            }
            return null;
        }

        //判断是否存在该链接名的元件
        public static function hasDefinition(name:String)
        {
            if (((name != '') || name != null))
            {
                return ApplicationDomain.currentDomain.hasDefinition(name);
            }
            return false;
        }

    }
}
复制代码

 悲剧,不能传附件。可怜我做在UI里的花花啊。。。

分享到:
评论

相关推荐

    SpringBoot AOP切面类三种写法(源代码)

    1.2使用方法 1.3创建项目并添加maven依赖 1.4 创建Javabean测试类 1.5 创建切面 1.6 测试类 1.7 测试结果 1.8 结论 1.9 代理方式的切换 1.9.1 设计一个接口ManInterface 1.9.2 javaBean目标类Man实现ManInterface...

    FLEX 系统管理器 SystemManager

    SystemManager是Flex应用的主控者,它控制着应用窗口,Application实例,弹出窗口,cursors,并管理着ApplicationDomain中的类。SystemManager是FlashPlayer实例化的第一个类,它存储了主应用窗

    SAD上机实验

    面向对象的系统分析和设计的主要目的是完成对某个特定应用论域(application domain)的分析和系统的建模。应完成的主要工作是描述系统中的对象、对象的属性和操作、对象的动态特性、对象间的构造关系和通信关系等,...

    系统分析与设计课件

    面向对象的系统分析和设计的主要目的是完成对某个特定应用论域(application domain)的分析和系统的建模。应完成的主要工作是描述系统中的对象、对象的属性和操作、对象的动态特性、对象间的构造关系和通信关系等,...

    Spring中文帮助文档

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring API

    6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...

    Spring 2.0 开发参考手册

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    java 面试题 总结

    以下程序使用内部类实现线程,对j增减的时候没有考虑顺序问题。 public class ThreadTest1{ private int j; public static void main(String args[]){ ThreadTest1 tt=new ThreadTest1(); Inc inc=tt.new Inc(); ...

    spring chm文档

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...

    Spring-Reference_zh_CN(Spring中文参考手册)

    6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...

    ddns+java+阿里云动态修改DDNS+外网IP

    使用时在ddns\src\main目录下找到application.yml配置文件然后更改成自己的信息 ddns: aliyun: domain: xxxxxxx.com #主域名 regionId: cn-shenzhen #地域信息 keyword: api #解析-主机记录 accessKeyId: L111r...

    基于SpringBoot快速开发的爬虫项目源码+项目使用说明+sql数据库.zip

    1. 准备有效MongoDB、MySQL数据库,并配置到resources/application-dev.yml 2. 初始化数据库 mongoDB脚本:doc/mongoDB.sql MySQL脚本:doc/stock.sql 2.2 启动程序 1. 执行 src/test/java/...

    超级有影响力霸气的Java面试题大全文档

    由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。 21、heap和stack有什么区别。  ...

    SimpleTaskSystem包含NuGet

    DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等) Castle windsor (依赖注入容器) Entity Framework 6 \ NHibernate,数据迁移 Log4Net(日志记录) ...

    KCTest:使用.NET Core和DDD使用Clean Architecture的示例Web API实现

    KCTest.Domain-此程序集包含公用,实体和接口。 KCTest.Application-该程序集包含所有服务实现。 KCTest.Infrastructure-此程序集包含数据持久性基础结构。 KCTest.API-此程序集是Web api主机。 KCTest.Tests-该...

    CI框架(CodeIgniter)实现ThinkPHP一样的二级域名解析

    本例主要实现在CI框架中像ThinkPHP一样的二级...放到\application\config中 4. 另附二级域名重写apache的配置文件 httpd-vhosts.conf。 无兄弟,不编程。 希望能与大家共同交流进步。 @author : qikelaiye@gmail.com

    asp.net知识库

    使用Relations建立表之间的关系并却使用PagedDataSource类对DataList进行分页 通过作业,定时同步两个数据库 SQLSERVER高级注入技巧 利用反射实现ASP.NET控件和数据实体之间的双向绑定,并且在客户端自动验证输入的...

    AbpConsole.rar

    DDD领域驱动设计 (Entities、Repositories、Domain Services、Domain Events、Application Services、DTOs等) Castle windsor (依赖注入容器) Entity Framework 6 \ NHibernate,数据迁移 Log4Net(日志记录...

    基于java开发的开源网址导航网站项目源码+数据库+项目说明.zip

    可以在 docker run -e 指定环境变量的方式,也可以使用 -v /path/to/application.yml:/root/webstack/config/application.yml 的方式映射配置文件 ### 使用 docker run -e 方式设置环境变量 支持设置的环境变量有 ...

    java-servlet-api.doc

    通过执行这个接口,Servlet有权使用ServletOutputStream类来向客户端返回数据。 多线程和映射\r 在多线程的环境下,Servlet必须能处理许多同时发生的请求。例外的情况是这个Servlet执行了SingleThreadModel接口,...

Global site tag (gtag.js) - Google Analytics