您的位置:首页 > 移动开发

AS3应用程序模块化开发与ApplicationDomain

2009-12-01 15:39 155 查看
当程序越来越大,我们需要把它拆分成多个swf,在需要的时候动态加载。拆分时应该尽量把不同的类编译进唯一的swf,避免因swf文件增多而使整个程序的文件尺寸增大。 按此原则可以拆分出以下两种swf,借助 ApplicationDomain 共享其代码和资源。

模块(Module)
按照程序逻辑,可以拆分出多个“功能模块”,如“注册”、“管理”等等;按照游戏或社区类程序的关卡或场景,可以拆分出不同的“场景模块”。
这些模块不是主程序运行必须的,只在需要的时候加载

运行时共享库(RSL)

主场景或者多个模块通用的资源,比如位图、声音、设计好的页面元素等,可作为“库”在主程序运行前加载。可以整套更换的皮肤(skin)只需先加载一套。

----------------------------------------------
applicationDomain 属性

public var applicationDomain:ApplicationDomain = null
指定用于 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 属性可供您选择使用:

加载器的 ApplicationDomain 的子级(模块)。默认值。 可以使用语法 new ApplicationDomain(ApplicationDomain.currentDomain) 显式表示这种选择。 这将允许所加载的 SWF 文件直接使用父级的类,例如,可通过编写 new MyClassDefinedInParent() 来使用。 但是父级则不能使用此语法;如果父级要使用子级的类,它必须调用 ApplicationDomain.getDefinition() 来检索它们。
这种选择的优点是:
1、如果子级定义的类与父级已经定义的类同名,不会出现错误结果;
2、子级只会继承父级对该类的定义,除非子级或父级调用 ApplicationDomain.getDefinition() 方法来检索子级的冲突定义,否则将不使用此定义。

加载器自己的 ApplicationDomain (共享库) 。使用 ApplicationDomain.currentDomain 时请使用此应用程序域。 加载完成后,父级和子级可以直接使用对方的类。
如果子级试图定义的类与父级已经定义的类同名,将出现错误并放弃加载。

系统 ApplicationDomain 的子级(独立运行的程序或模块) 。使用 new ApplicationDomain(null) 时请使用此应用程序域。 这将完全分离加载方和被加载方,从而允许它们使用相同的名称定义各自版本的类并且不会产生冲突或隐藏。 一方查看另一方的类的唯一方式是调用 ApplicationDomain.getDefinition() 方法。

其它 ApplicationDomain 的子级。有时可能会有更复杂的 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 是存放AS3定义(包括类、方法、接口等)的容器。
使用Loader类加载swf时可以通过指定ApplicationDomain 参数将swf加载到不同的域(Domain):

代码

public function show(p_parent:DisplayObjectContainer,

rest):void
{
var libClass:Class = this.getClass("net.eidiot.appDomainDemo.Libaray");
if (libClass != null)
this.initUi(libClass, rest);
}

override protected function initUi(p_libClass:Class, p_rest:Array = null):void
{
this.addUi(this.getClass(p_libClass.BG_NAME), "结果");
var resultFunc:Function = p_libClass.getResult;
var userName:String = p_rest[0];
this.addChild(resultFunc(userName));
}

  注意initUi()方法分别使用了共享库中Libaray类的静态属性BG_NAME和静态方法getResult()。但是直接调用此静态方法会报错,可以先用 resultFunc 变量取出此方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: