`
NewTamato
  • 浏览: 103498 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

转 flash applicationDomain

 
阅读更多

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

  • 模块(Module)
    按照程序逻辑,可以拆分出多个“功能模块”,如“注册”、“管理”等等;按照游戏或社区类程序的关卡或场景,可以拆分出不同的“场景模块”。这些模块不是主程序运行必须的,只在需要的时候加载。
  • 运行时共享库(RSL)
    主场景或者多个模块通用的资源,比如位图、声音、设计好的页面元素等,可作为“库”在主程序运行前加载。可以整套更换的皮肤(skin)只需先加载一套。

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

   ApplicationDomain使用类似于显示列表(DisplayList)的树形结构。 相对于舞台(Stage) ,可以认为 ApplicationDomain 最根部的是系统域(system domain),包含 Flash Player 核心类定义。主程序所在的域(以下简称主域)就是它唯一的子域,类似于Stage下的文档类(Document Class)。
  一个fla文档类里代码:

this . stage . addChild ( mySprite ) ;
this . addChild ( myMC ) ;
this . addChild ( myShape ) ;
运行后的显示列表:
饿
ApplicationDomain 的类似结构:
2
  • 加载到子域(模块)
    类似于“继承”,子域可以直接获得父域所有的类定义,反之父域得不到子域的。和继承关系不同的是,如果子域中有和父域同名的类,子域定义会被忽略而使用父域的定义。
  • 加载到同域(运行时共享库)
    类似集合里的合并关系。被加载swf里的所有类定义被合并到当前域中可以直接使用。和加载到子域相同,和当前域同名的定义也会被忽略。
  • 加载到新域(独立运行的程序或模块)
    swf载入指定域之前,先要检查该域及其父域中是否存在同名类,重复定义一概忽略。如果加载别人写的程序,或者使用旧版本的主程序加载新版本的模块,为避免类名冲突就要加载到新域独立运行以使用自己的类。

  模块加载到同域不是一样可以吗?为何要加载到子域呢?好处就在于,卸载一个加载到子域的模块时,只要确保清除所有到该模块的引用,模块的所有类定义将被垃圾回收(Garbage Collection)。
  有两种方式可以访问 ApplicationDomain :

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

  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 ;
    
var userName : String = p_rest [ 0 ] ;
    
this . addChild ( resultFunc ( userName )) ;
}

  注意initUi()方法分别使用了共享库中Libaray类的静态属性BG_NAME和静态方法getResult()。但是直接调用此静态方法会报错,可以先用 resultFunc 变量取出此方法。详细内容请参考 源代码

实例效果演示
下载源文件 (rar 278K)

 

 

这篇文章在杜增强的博客看到,感谢他的分享。看完受益非浅!

分享到:
评论

相关推荐

    ApplicationDomain的误解,安全沙箱有关内容

    1. **系统级ApplicationDomain**:每个Flash Player实例都有一个顶级的`ApplicationDomain`,称为系统级`ApplicationDomain`,它是所有其他`ApplicationDomain`的父域。 2. **当前ApplicationDomain**:当一个新的...

    applicationDomain学习资料

    ApplicationDomain的概念在Flash和更广泛的编程领域中扮演着重要角色,尤其是在资源管理和跨文档资源共享方面。通过合理利用运行时共享库资源和创作时共享库资源,开发者可以构建更加高效、灵活且易于维护的应用程序...

    详细介绍ApplicationDomain和SecurityDomain

    在深入探讨ApplicationDomain和SecurityDomain之前,我们首先明确这两个概念的基本定义及其在Flash环境中的重要性。ApplicationDomain和SecurityDomain是Flash Player中用来管理和隔离不同内容的重要机制。它们分别...

    深入理解ApplicationDomain和SecurityDomain

    ### 深入理解ApplicationDomain和SecurityDomain #### 安全域(Security Domain)与应用程序域(Application Domain)概述 安全域与应用程序域是Flash Player中两种重要的沙箱概念,它们帮助开发者理解如何管理和...

    详解flash应用程序域

    通过使用`ApplicationDomain.currentDomain`或新建`ApplicationDomain`实例,开发者可以灵活地决定子SWF的定义应当放置在何处,从而实现对继承关系和资源访问的精细控制。 #### 结论 理解Flash应用程序域对于任何...

    Adobe Flash Player for IE v11.3.300.265

    Adobe Flash Player(Flash Player官方下载)是一个集成的多媒体播放器,让你在Web上享受更广泛的多媒体体验。Adobe Flash Player官方版可显示和播放多媒体内容,从数以千计的高度...— ApplicationDomain.getQualifie

    Flash Loading源程序

    如果需要指定类型,可以使用LoaderContext对象的checkPolicyFile和applicationDomain属性。 7. **内存管理**:加载的资源会占用内存,因此在不再需要时应卸载(unload)它们以释放内存。同时,注意避免内存泄漏,这...

    flash 远程加载资源文件及引用

    在多个SWF文件(如`login.swf`和`main.swf`)之间进行交互,可以利用`LoaderContext`和`ApplicationDomain`。通过设置`LoaderContext`的`applicationDomain`属性,可以控制加载的SWF是否能访问主SWF的类和变量: `...

    Flash As3.0 Web传递参数

    import flash.system.ApplicationDomain; import flash.display.MovieClip; var movieClip:MovieClip = this as MovieClip; var params:Object = movieClip.loaderInfo.parameters; trace("param1: " + params....

    Flash页游未来新技术:Adobe Alchemy

    Alchemy 引入了一种新的内存操作码机制,允许直接访问 ApplicationDomain 的内存区域,从而提高了性能。例如,可以通过 `ApplicationDomain.currentDomain.domainMemory.readInt()` 直接读取内存中的数据。这种机制...

    flex调用swf——swf可以转成具体的对象,而非MovieClip

    import flash.system.ApplicationDomain; import flash.events.Event; var loader:Loader = new Loader(); var context:LoaderContext = new LoaderContext(false, ApplicationDomain.currentDomain); // 假设你的...

    asp flash 上传 代码 能显示上传进度

    <embed src="upfile/main.swf" quality="high" bgcolor="#ffffff" width="342" height="38" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage=...

    ASP.NET 加Flash

    type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"/> ``` 这里的关键点包括: - `classid`和`codebase`属性用于指定Flash播放器的CLSID和版本信息。 - `width`...

    JS与FLASH相互调用0积分0积分

    <object type="application/x-shockwave-flash" data="example.swf" width="525" height="390" id="myFlash"> <param name="allowScriptAccess" value="sameDomain"/> <!-- 其他参数 --> var response = ...

    AS3 多线程

    在AS3中实现多线程,可以使用`flash.system.LoaderContext`和`flash.system.ApplicationDomain`这两个类。`LoaderContext`允许创建一个独立的运行环境,而`ApplicationDomain`则用来管理类的加载和命名空间。通过这...

    flash透明背景说明

    <embed src="myMovieName.swf" quality="high" bgcolor="#ffffff" width="550" height="400" name="myMovieName" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" ...

    flash资源加载策略

    通过Loader.contentLoaderInfo.applicationDomain.getDefinition()或getDefinitionByName()方法,可以在运行时获取并实例化这些资源。这种方式加载速度快,管理方便,尤其适合UI皮肤和即时显示的图标。然而,它要求...

    flash swf之间传值

    2. **使用LoaderContext和ApplicationDomain**: 在加载时,你可以设置`LoaderContext`的`applicationDomain`属性,使得A.SWF和B.SWF共享同一命名空间,从而可以直接访问彼此的公开变量。但这可能导致命名冲突,所以...

    网页FLASH播放器代码

    <script language="JavaScript"> var movie,timer,step,total,state=null,delay=100 function init(){//在 Flash 加载完成后初始化相关变量的函数 ...<embed name="movie" src="http://file.flash8.net/film/...

Global site tag (gtag.js) - Google Analytics