



















程序越来越大,我们需要把它拆分成多个swf,在需要的时候动态加载。拆分时应该尽量把不同的类编译进唯一的swf,避免因swf文件增多而使整个程序的文件尺寸增大。按此原则可以拆分出以下两种swf,借助 ApplicationDomain 共享其代码和资源。
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);
ApplicationDomain使用类似于显示列表(DisplayList)的树形结构。 相对于舞台(Stage) ,可以认为 ApplicationDomain 最根部的是系统域(system domain),包含 Flash Player 核心类定义。主程序所在的域(以下简称主域)就是它唯一的子域,类似于Stage下的文档类(Document Class)。
一个fla文档类里代码:
this.stage.addChild(mySprite); this.addChild(myMC); this.addChild(myShape);
运行后的显示列表:
ApplicationDomain 的类似结构:
ApplicationDomain 的 hasDefinition() 方法判断某定义是否存在,getDefinition() 获取指定的定义。下面以一个 例子 来介绍 ApplicationDomain 的具体用法和应用程序的拆分。
本例 有四个swf,shell.swf是主程序,lib.swf是共享库,login.swf和result.swf分别是“登录”和“结果”模块,所有的视 图元件都在共享库中。实际开发时可能有很多库,比如“位图库”、“音效库”、“模型通用库”等。“通用库”里存放多个模块共用的资源,比如此例中的背景元 素。而各个模块独有的资源还是放在各自的swf中。
主程序首先将共享库加载到同域,完成后将“登录模块”加载到子域。主程序可以像普通的视觉 对象(DisplayObject)一样操作加载的模块:监听事件、调用方法。因为编译器不会识别未定义的类,为使用强类型,建议为主类和模型定义相应的 接口,使用少量的重复代码协助编程。
private function showModule(p_module : IModule) : void
{
if (this.m_moduleList[0] == "login.swf")
{
p_module.show(this);
p_module.addEventListener("login", this.onLogin);
}
else
{
p_module.show(this, this.m_userName);
}
}
模块“继承”了主程序和共享库的所有类和资源,可以通过 ApplicationDomain.currentDomain.getDefinition() 来获取相应的类。注意获取不存在的类会抛出一个 ReferenceError。
protected function getClass(p_name : String) : Class
{
try
{
return ApplicationDomain.currentDomain.getDefinition(p_name) as Class;
}
catch (p_e : ReferenceError)
{
trace("定义 " + p_name + " 不存在");
return null;
}
return null;
}
登录模块获取库中的界面元素,并在点击按钮后抛出事件。Event类不允许带参数,必须使用继承Event的自定义事件抛出参数。主程 序可以把模块的自定义事件也编译进去(这样就增大了整个程序的文件尺寸),或者让监听模块事件的函数接受一个Objcet参数,以获取其动态参数。
private function onLogin(p_e : Object) : void
{
this.m_userName = p_e.userName;
var login : IModule = p_e.currentTarget;
login.removeEventListener("login", this.onLogin);
login.dispose();
this.loadSwf();
}
主程序收到事件之后卸载注册模块,加载“结果模块”到子域,并将登录模块传出的”userName”参数传给结果模块。
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;
ar userName : String = p_rest[0];
this.addChild(resultFunc(userName));
}
注意initUi()方法分别使用了共享库中Libaray类的静态属性BG_NAME和静态方法getResult()。但是直接调用此方法会报错,可以先用 resultFunc 变量取出此方法。详细内容请参考 源代码
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。