Flex-LoaderContext applicationDomain 属性详解
2012年01月11日
在API中此属性的解释为:指定用于 Loader.load() 或 Loader.loadBytes() 方法的应用程序域。只应在加载使用 ActionScript 3.0 编写的 SWF 文件(不是图像或使用 ActionScript 1.0 或 ActionScript 2.0 编写的 SWF 文件)时才使用此属性。
每个安全域被分成一个或多个由 ApplicationDomain 对象表示的应用程序域。应用程序域并不是用于安全目的;它们用于管理 ActionScript 代码的协作单元。如果是从其他域加载 SWF 文件,并允许将它放置到另外一个安全域中,则您将无法控制所加载的 SWF 文件被放置到哪个应用程序域中;即使您指定应选择某个应用程序域,也会忽略。但是,如果是将 SWF 文件加载到您自己的安全域中(因为此 SWF 文件来自您自己的域,或者您正在将它导入到您的安全域中),您就可以控制为所加载的 SWF 文件选择哪个应用程序域。
在 LoaderContext.applicationDomain 中,您只可以传递您自己的安全域中的应用程序域。如果试图传递任何其他安全域中的应用程序域,则会引发 SecurityError 异常。
有四种 ApplicationDomain 属性可供您选择使用:
[b]加载器的 ApplicationDomain 的子级。[/b]默认值。可以使用语法 new ApplicationDomain(ApplicationDomain.currentDomain) 显式表示这种选择。这将允许所加载的 SWF 文件直接使用父级的类,例如,可通过编写new MyClassDefinedInParent() 来使用。但是父级则不能使用此语法;如果父级要使用子级的类,它必须调用 ApplicationDomain.getDefinition() 来检索它们。这种选择的优点是,如果子级定义的类与父级已经定义的类同名,不会出现错误结果;子级只会继承父级对该类的定义,除非子级或父级调用 ApplicationDomain.getDefinition() 方法来检索子级的冲突定义,否则将不使用此定义。[b]加载器自己的 ApplicationDomain。[/b]使用 ApplicationDomain.currentDomain 时请使用此应用程序域。加载完成后,父级和子级可以直接使用对方的类。如果子级试图定义的类与父级已定义的类同名,则使用父类并忽略子类。[b]系统 ApplicationDomain 的子级。[/b]使用 new ApplicationDomain(null) 时请使用此应用程序域。这将完全分离加载方和被加载方,从而允许它们使用相同的名称定义各自版本的类并且不会产生冲突或隐藏。一方查看另一方的类的唯一方式是调用 ApplicationDomain.getDefinition() 方法。[b]其他 ApplicationDomain 的子级。[/b]有时可能会有更复杂的 ApplicationDomain 层次结构。可以将 SWF 文件从您自己的 SecurityDomain 加载到任何 ApplicationDomain 中。例如,new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain) 将 SWF 文件加载到当前域父级的父级的新子级中。
加载完成后,为调用 ApplicationDomain.getDefinition(),任一方(加载方或被加载方)都可能需要找到它自己的 ApplicationDomain 或另一方的 ApplicationDomain。任一方都可以通过使用ApplicationDomain.currentDomain 来检索对它自己的应用程序域的引用。执行加载的 SWF 文件可以通过 Loader.contentLoaderInfo.applicationDomain 来检索对被加载的 SWF 文件的 ApplicationDomain 的引用。如果被加载的 SWF 文件知道自己的加载方式,则它可以找到执行加载的 SWF 文件的 ApplicationDomain 对象。例如,如果子级是以默认方式被加载的,则它可以通过使用 ApplicationDomain.currentDomain.parentDomain 找到执行加载的 SWF 文件的应用程序域。
我们通常喜欢使用ApplicationDomain.currentDomain来作为LoaderContext的applicationDomain的属性值。一般情况下这种做法是没有问题的,但是如果我们需要使用 ApplicationDomain.getDefinition()方法来使用SWF中的一些类定义的时候就要小心了。因为使用这种方法加载的SWF,其中的类定义会一直在内存中驻留,并且与框架中的类定义融为一起,如果要在运行期间加载其他的类似的SWF,并希望使用其中的类定义,就会出现问题,这时你获取的类定义依然是上次加载的类定义。因为这个地方会以已存在的类定义为主。这个时候应当使用new ApplicationDomain(null)作为其属性值,此时每个SWF就会有其各自专门的域,自然也就不会有冲突了。
2012年01月11日
在API中此属性的解释为:指定用于 Loader.load() 或 Loader.loadBytes() 方法的应用程序域。只应在加载使用 ActionScript 3.0 编写的 SWF 文件(不是图像或使用 ActionScript 1.0 或 ActionScript 2.0 编写的 SWF 文件)时才使用此属性。
每个安全域被分成一个或多个由 ApplicationDomain 对象表示的应用程序域。应用程序域并不是用于安全目的;它们用于管理 ActionScript 代码的协作单元。如果是从其他域加载 SWF 文件,并允许将它放置到另外一个安全域中,则您将无法控制所加载的 SWF 文件被放置到哪个应用程序域中;即使您指定应选择某个应用程序域,也会忽略。但是,如果是将 SWF 文件加载到您自己的安全域中(因为此 SWF 文件来自您自己的域,或者您正在将它导入到您的安全域中),您就可以控制为所加载的 SWF 文件选择哪个应用程序域。
在 LoaderContext.applicationDomain 中,您只可以传递您自己的安全域中的应用程序域。如果试图传递任何其他安全域中的应用程序域,则会引发 SecurityError 异常。
有四种 ApplicationDomain 属性可供您选择使用:
[b]加载器的 ApplicationDomain 的子级。[/b]默认值。可以使用语法 new ApplicationDomain(ApplicationDomain.currentDomain) 显式表示这种选择。这将允许所加载的 SWF 文件直接使用父级的类,例如,可通过编写new MyClassDefinedInParent() 来使用。但是父级则不能使用此语法;如果父级要使用子级的类,它必须调用 ApplicationDomain.getDefinition() 来检索它们。这种选择的优点是,如果子级定义的类与父级已经定义的类同名,不会出现错误结果;子级只会继承父级对该类的定义,除非子级或父级调用 ApplicationDomain.getDefinition() 方法来检索子级的冲突定义,否则将不使用此定义。[b]加载器自己的 ApplicationDomain。[/b]使用 ApplicationDomain.currentDomain 时请使用此应用程序域。加载完成后,父级和子级可以直接使用对方的类。如果子级试图定义的类与父级已定义的类同名,则使用父类并忽略子类。[b]系统 ApplicationDomain 的子级。[/b]使用 new ApplicationDomain(null) 时请使用此应用程序域。这将完全分离加载方和被加载方,从而允许它们使用相同的名称定义各自版本的类并且不会产生冲突或隐藏。一方查看另一方的类的唯一方式是调用 ApplicationDomain.getDefinition() 方法。[b]其他 ApplicationDomain 的子级。[/b]有时可能会有更复杂的 ApplicationDomain 层次结构。可以将 SWF 文件从您自己的 SecurityDomain 加载到任何 ApplicationDomain 中。例如,new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain) 将 SWF 文件加载到当前域父级的父级的新子级中。
加载完成后,为调用 ApplicationDomain.getDefinition(),任一方(加载方或被加载方)都可能需要找到它自己的 ApplicationDomain 或另一方的 ApplicationDomain。任一方都可以通过使用ApplicationDomain.currentDomain 来检索对它自己的应用程序域的引用。执行加载的 SWF 文件可以通过 Loader.contentLoaderInfo.applicationDomain 来检索对被加载的 SWF 文件的 ApplicationDomain 的引用。如果被加载的 SWF 文件知道自己的加载方式,则它可以找到执行加载的 SWF 文件的 ApplicationDomain 对象。例如,如果子级是以默认方式被加载的,则它可以通过使用 ApplicationDomain.currentDomain.parentDomain 找到执行加载的 SWF 文件的应用程序域。
我们通常喜欢使用ApplicationDomain.currentDomain来作为LoaderContext的applicationDomain的属性值。一般情况下这种做法是没有问题的,但是如果我们需要使用 ApplicationDomain.getDefinition()方法来使用SWF中的一些类定义的时候就要小心了。因为使用这种方法加载的SWF,其中的类定义会一直在内存中驻留,并且与框架中的类定义融为一起,如果要在运行期间加载其他的类似的SWF,并希望使用其中的类定义,就会出现问题,这时你获取的类定义依然是上次加载的类定义。因为这个地方会以已存在的类定义为主。这个时候应当使用new ApplicationDomain(null)作为其属性值,此时每个SWF就会有其各自专门的域,自然也就不会有冲突了。