MovieClipLoader类详解
2009年11月03日
本文深入研究了MovieClipLoader类的特性,并剖析了MovieClipLoader类的实现缺陷,假定读者对此类有一定的了解,并可以使用该类进行简单的诸如loading的开发,但是本文并不是一篇介绍loading的文章。
使用moviecliploader下载过多的位图会带来计算机网络连接的拥塞,即使使用unloadClip方法取消下载,仍然不会有好转,引起这个现象的原因与这个类的实现细节有关系,我们虽然不能看到其实现的原理,但是通过它的表现,可以对其特性有所认识。
MovieClipLoader可以胜任一般的应用,但是对于一些大量的下载任务,如果使用不当,可能带来严重的网络负担和非常差的用户体验。下面分别讨论MovieClipLoader类的各个方法。
loadClip(MovieClipLoader.loadClip 方法)
public loadClip(url:String, target:Object) : Boolean
下文部分摘自Flash Professional 8 官方文档。
QUOTE:
在播放原始影片时,将 SWF、JPEG、渐进式 JPEG、非动画 GIF 或 PNG 文件加载到 Flash Player 中的影片剪辑中。如果您加载 GIF 动画,仅显示第一帧。使用此方法可以一次显示多个 SWF 文件,并且无需加载另一个 HTML 文档即可在 SWF 文件间进行切换。
使用 loadClip() 方法代替 loadMovie() 或 MovieClip.loadMovie() 具有许多优点。通过使用侦听器对象来实现下列处理函数。通过使用 MovieClipLoader.addListener(listenerObject) 向 MovieClipLoader 类注册侦听器,可以激活该侦听器。
在加载开始时调用 MovieClipLoader.onLoadStart 处理函数。
在无法加载剪辑时调用 MovieClipLoader.onLoadError 处理函数。
在加载进程正进行时调用 MovieClipLoader.onLoadProgress 处理函数。
在文件完成下载但已加载的影片剪辑的方法和属性尚不可用时调用 MovieClipLoader.onLoadComplete 处理函数。在 onLoadInit 处理函数之前调用此处理函数。
在执行该剪辑的第一帧中的动作后调用 MovieClipLoader.onLoadInit 处理函数,以便您可以开始处理加载的剪辑。在 onLoadComplete 处理函数之后调用此处理函数。在大多数情况下,请使用 onLoadInit 处理函数。
加载到影片剪辑的 SWF 文件或图像会继承该影片剪辑的位置、旋转和缩放属性。可以用该影片剪辑的目标路径来定位加载的影片。
您可以使用 loadClip() 方法将一个或多个文件加载到单个影片剪辑或级别中;将 MovieClipLoader 侦听器对象作为参数传递给正加载的目标影片剪辑实例。或者,您可以为加载的每个文件创建不同的 MovieClipLoader 对象。
使用 MovieClipLoader.unloadClip() 可删除用此方法加载的影片或图像,或者取消正在进行中的加载操作。
首先需要指出的是,loadClip方法对于Flash编程人员来说是多线程的,不管其内部实现机制如何,一个事实可以证明这一点:我们可以使用 loadClip方法同时下载多个图片,并把不同的图片放在不同或者相同的电影剪辑当中。(文档中仅仅指出可以放在同一个剪辑当中)。
第二点,MovieClipLoader.onLoadStart处理函数并不是调用loadClip后会立即触发。文档称,当被加载的剪辑或者图片的第一个字节被写入用户磁盘中时,此函数被调用。可以确定,当网络连接不可用或者被下载资源不可用的时候就可能用原不会触发此事件。
unloadClip(MovieClipLoader.unloadClip 方法)
public unloadClip(target:Object) : Boolean
下文红色部分摘自Flash Professional 8 官方文档。
QUOTE:
删除通过使用 MovieClipLoader.loadClip() 加载的影片剪辑。如果您在正加载影片时发出此命令,则调用 MovieClipLoader.onLoadError。
可用性:ActionScript 1.0;Flash Player 7
参数
target:Object - 传递至对 my_mcl.loadClip() 的相应调用的字符串或整数。
返回
Boolean - 一个布尔值。如果删除影片剪辑成功,则返回 true;否则返回 false。
示例
下面的示例将图像加载到名为 image_mc 的影片剪辑中。如果单击影片剪辑,则会删除该影片剪辑,并且信息会显示在"输出"面板中。
this.createEmptyMovieClip("image_mc", this.getNextHighestDepth());
var mclListener:Object = new Object();
mclListener.onLoadInit = function(target_mc:MovieClip) {
target_mc._x = 100;
target_mc._y = 100;
target_mc.onRelease = function() {
trace("Unloading clip...");
trace("\t name: "+target_mc._name);
trace("\t url: "+target_mc._ur ;
image_mcl.unloadClip(target_mc);
};
};
var image_mcl:MovieClipLoader = new MovieClipLoader();
image_mcl.addListener(mclListener);
image_mcl.loadClip("http://www.helpexamples.com/flash/images/image1.jpg", image_mc);
此方法是我们讨论的核心所在。loadClip文档称:使用 MovieClipLoader.unloadClip() 可删除用此方法加载的影片或图像,或者取消正在进行中的加载操作。我们知道,loadClip方法是需要占用网络连接核内存资源的,我们寄希望于一旦调用 unloadclip则立即释放网络连接和内存资源。但是事与愿违!这是MovieClipLoader方法的关键问题。当AS调用 MovieClipLoader.unloadClip()之后,并不一定会马上释放资源。当我们使用MovieClipLoader下载大量的图片的时候,虽然我们在调用unloadClip之后才下载新的图片,但是网络连接的使用将进一步累积增大,导致网络连接的暂时阻塞。
经过测试,调用loadClip方法之后,立即调用unloadClip方法是丝毫不起作用的,下载过程会继续进行,并且MovieClipLoader类的事件处理函数仍然会被调用。这看起来非常出乎人的意料之外!而且非常不合理,但是事实就是如此。另外,如果手动将被加载对象的目的剪辑删除(unloadMovie或者removeMovieClip),这将删除舞台上的剪辑,但是仍然不能释放MovieClipLoader所占用的资源。
事实证明,当MovieClipLoader.onLoadStart被调用之后(注意:这是loadClip开始之后第一个可能被触发的事件),再次使用 unloadClip方法,将会删除被加载的剪辑,但是同时网络连接也会被释放。但是这样做的并没有太大的意义,因为从网络占用开始到下载第一个字节,期间的资源消耗是不可消除的,但这卡恰又是关键的资源。这段无意义的资源占用会字节导致用户计算机的网络阻塞,表现为上网速度突然降低,几秒钟之后恢复正常(这要看用户的网络速度如何以及同时下载的图片数有多大)。
这里判断网络连接被释放的方法有点特别。因为当Flash Professional 8在测试影片时,如果Flash正在使用网络连接来下载数据,这是关闭Flash测试窗口会导致Flash 8 Professional开发环境的异常。这个异常并不会给用户以任何提示,但是此后的影片测试动作将无效,不能开启影片测试窗口,甚至可能导致 Flash崩溃。
当onLoadStart事件触发之后,使用unloadClip,并且立即关闭测试窗口,不会带来上述的开发环境异常的问题,因此我猜测网络连接已经释放了。当然,肯定是有更好的方式去判断是否释放了网络连接。
unloadClip 的存在的另外一个问题是MovieClipLoader.onLoadError事件的触发问题。文档指出:如果您在正加载影片时发出此命令,则调用 MovieClipLoader.onLoadError。但是通过我的测试,不论何时调用了unloadClip方法, MovieClipLoader.onLoadError都不会被触发!这是另一个非常惊人的现象!
现在我还没有找到一个方法,可以彻底的从内存中删除一个对象。我们知道,as是使用垃圾收集机制来管理内存的,我们并不能直接调用垃圾收集动作,也就是说,大多数时候,我们设置一个对象的唯一引用为null,那么可以判断这个对象已经符合垃圾收集的条件,但是这个对象并不会立即被破坏,它所占用的内存和其他资源并不会立即被释放。因此,我们没有办法在所有时候立即释放MovieClipLoader所占用的资源。
onLoadInit(MovieClipLoader.onLoadInit 事件侦听器)onLoadInit = function([target_mc:MovieClip]) {}
下文红色部分摘自Flash Professional 8 官方文档。
QUOTE:
当执行加载的剪辑的第一帧上的动作时调用。在调用此侦听器后,您可以设置属性、使用方法,还可以与加载的影片交互。对通过使用 MovieClipLoader.addListener() 添加的侦听器对象调用此侦听器。
target_mc 的值标识作为这一调用的目标的影片剪辑。此参数在使用同一组侦听器加载多个文件时非常有用。
这里需要补充一点:onLoadInit是在调用被加载剪辑的第一帧的代码之后被触发。onLoadCompelete触发是在被加载对象的最后一个字节被写入用户磁盘的时候被调用,在此之后和onLoadInit之前,被加载对象的内部数据是不可用的。然而,这里的内部数据指的是被加载对象的帧代码以及其子剪辑,被加载对象本身的属性和方法是有效的!也就是说,将图片加载到mc中的过程中的任何时候,mc._x是始终可以被使用的。
最终结果:今天我使用sniffer观察IP数据包之后,发现多个MovieclipLoader会共用TCP:http网络连接,只要前一个任务下载完毕,就可以释放连接给下一个任务使用,这是MovieclipLoader实现中非常明智的地方。但是如果尚没有任务下载完毕,也就是没有空闲TCP: http网络连接,就会创建新连接。
因此如果不断下载新图片并且在旧尚未下载完之前移除target_mc,由于 MovieClipLoader.unloadClip、MovieClip.removeMovieClip以及 MovieClip.unloadClip都只能仅仅删除场景尚的图片,而不能立即释放TCP:http网络连接,这样导致每添加一个新任务都会创建新连接,这将大大耗费资源,最终导致网络阻塞!!!
至此MovieclipLoader的关键问题就很明显了:MovieclipLoader类没有提供立即释放网络连接的方法,这是问题的根源。
注:本文涉及内容可能会有争议,如有疏漏或者错误,敬请指正。
附录:本文用户讨论的实例的代码如下,由于个人站空间有限,不能提供源文件下载。主场景中有两个按钮,实例名为start和cancel。为了使trace有效,请在开发环境中测试这些代码,而不是发布之后运行。
//http://www.cloudward.net/map/flash_51ditu.swf
var mcl=new MovieClipLoader();
var started;
var mc:MovieClip;
start.onRelease=function(){
started=true;
mcm=_root.createEmptyMovieClip("mcm",10);
mc=mcm.createEmptyMovieClip("mc",11);
mcl.loadClip("http://www.cloudward.net/map/flash_51ditu.swf",mc);
}
cancel.onRelease=function(){
trace(_root.mcm);
_root.mcm.removeMovieClip();
//unloadMovie(_root.mc);
//mcl.unloadClip(mc);
}
var listener:Object=new Object();
listener.onLoadComplete=function(){
trace("onLoadComplete");
}
listener.onLoadError=function(){
trace("onLoadError");
}
listener.onLoadStart=function(mc){
//mc.unloadMovie();
trace("onLoadStart");
mcl.unloadClip(mc);
}
this.onEnterFrame=function(){
var o:Object=mcl.getProgress(mc);
//if(started && o.bytesLoaded!=o.bytesTotal)
//trace(Math.round(o.bytesLoaded/o.bytesTotal*100));
}
mcl.addListener(listener);
发表评论
-
A*搜索算法
2012-01-20 02:24 769A*搜索算法 2011年03月28 ... -
红黑树
2012-01-20 02:24 601红黑树 2011年03月28日 学无止境,把这几年收藏的 ... -
Vertex Shader的世界:
2012-01-20 02:24 944Vertex Shader的世界: 2011 ... -
大规模场景的消隐技术
2012-01-20 02:24 577大规模场景的消隐技术 ... -
Vertex Shader 结构
2012-01-20 02:23 859Vertex Shader 结构 2011年04月24日 ... -
网上淘来的文章,对自己有点帮助
2012-01-19 10:13 717网上淘来的文章,对自己 ... -
英语的重要性
2012-01-19 10:13 504英语的重要性 2011年02月28日 英语的重要性 全球 ... -
背诵再背诵
2012-01-19 10:13 588背诵再背诵 2010年06月07 ... -
关于计算机图形学的学习资料建议
2012-01-17 02:54 770关于计算机图形学的学习资料建议 2010年07月03日 ... -
<<游戏是这样写成的>>(OpenGL ES,Objc++,MD2模型显示,粒子系统)
2012-01-17 02:54 919>(OpenGL ES,Objc++,MD2模型显示,粒 ... -
怎样用OpenGL在某一位置上写字符串?
2012-01-17 02:54 622怎样用OpenGL在某一位置上写字符串? 2011年11月2 ... -
Flash开发移动设备技巧
2012-01-15 22:32 507Flash开发移动设备技巧 ... -
photoshop CS3 脚本入门
2012-01-15 22:32 832photoshop CS3 脚本入门 2009年09月14日 ... -
AS3 编程易犯盲点――绝对对您有帮助,新手们都来看看吧
2012-01-15 22:32 676AS3 编程易犯盲点――绝对对您有帮助,新手们都来看看吧 2 ... -
flash复习2
2012-01-15 22:32 953flash复习2 2010年01月21日 ...
相关推荐
在asp程序中用进度条显示动态加载图片的进度
movieClipLoader()类用于实现在 SWF、JPEG、GIF 和 PNG 文件正被加载到影片剪辑中时提供状态信息的侦听器回调。若要使用 MovieClipLoader 功能,请使用 MovieClipLoader.loadClip() 代替 loadMovie() 或 MovieClip....
构造函数 Array 类、Boolean 类、Camera 类、Color 类、ContextMenu 类、ContextMenuItem 类、Date 类、Error 类、LoadVars 类、LocalConnection 类、Microphone 类、NetConnection 类、NetStream 类、Number 类、...
推荐了国内外对推荐系统的讲解相关资源
全渠道电商平台业务中台解决方案.pptx
云计算企业私有云平台建设方案.pptx
本代码是基于python pytorch环境安装的。 下载本代码后,有个requirement.txt文本,里面介绍了如何安装环境,环境需要自行配置。 或可直接参考下面博文进行环境安装。 https://blog.csdn.net/no_work/article/details/139246467 如果实在不会安装的,可以直接下载免安装环境包,有偿的哦 https://download.csdn.net/download/qq_34904125/89365780 安装好环境之后, 代码需要依次运行 01数据集文本生成制作.py 02深度学习模型训练.py 和03pyqt_ui界面.py 数据集文件夹存放了本次识别的各个类别图片。 本代码对数据集进行了预处理,包括通过在较短边增加灰边,使得图片变为正方形(如果图片原本就是正方形则不会增加灰边),和旋转角度,来扩增增强数据集, 运行01数据集文本制作.py文件,会就读取数据集下每个类别文件中的图片路径和对应的标签 运行02深度学习模型训练.py就会将txt文本中记录的训练集和验证集进行读取训练,训练好后会保存模型在本地
尺寸与分辨率:该显示屏的尺寸为0.96英寸,常见分辨率为128x64像素,意味着横向有128个像素点,纵向有64个像素点。这种分辨率足以显示基本信息和简单的图形。 显示技术:OLED(有机发光二极管)技术使得每个像素都能自发光,不需要背光源,因此对比度高、色彩鲜艳、视角宽广,且在低亮度环境下表现更佳,同时能实现更低的功耗。 接口类型:这种显示屏通常支持I²C(IIC)和SPI两种通信接口,有些型号可能还支持8080或6800并行接口。I²C接口因其简单且仅需两根数据线(SCL和SDA)而广受欢迎,适用于降低硬件复杂度和节省引脚资源。 驱动IC:常见的驱动芯片为SSD1306,它负责控制显示屏的图像显示,支持不同显示模式和刷新频率的设置。 物理接口:根据型号不同,可能有4针(I²C接口)或7针(SPI接口)的物理连接器。 颜色选项:虽然大多数0.96寸OLED屏为单色(通常是白色或蓝色),但也有双色版本,如黄蓝双色,其中屏幕的一部分显示黄色,另一部分显示蓝色。
2024年欧洲高端家用P1.29 LED显示屏市场主要企业市场占有率及排名
5G智慧校园顶层设计方案.pptx
介绍了通过引进 ActiveX控件 MSComm ,在 Delphi 6. 0 编程环境下 ,实现上位机与 Omron C200H PLC串行通信的一般方法 ,并给出了工程实例。该方法简单可靠、便于移植、实用性强 ,在工业控制中有着广泛的用途。
程序设计训练之 Rust 编程语言 第四讲:泛型、特型与生命周期
山寨版的神州数码802.1x认证supplicant,基于pcap库的C语言的跨平台的原生客户端。
数字乡村建设方案.pptx
基于CRT(远程访问终端)+ARM(GEC)+Linux+C语言的视频监控系统
建筑结构水电欧式6套(14.5x20.2)\施工图\A型施工图-建筑-空施00.dwg
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
21121344 马丽娟.doc
C++与操作系统等面试题63