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 762A*搜索算法 2011年03月28 ... -
红黑树
2012-01-20 02:24 597红黑树 2011年03月28日 学无止境,把这几年收藏的 ... -
Vertex Shader的世界:
2012-01-20 02:24 938Vertex Shader的世界: 2011 ... -
大规模场景的消隐技术
2012-01-20 02:24 574大规模场景的消隐技术 ... -
Vertex Shader 结构
2012-01-20 02:23 852Vertex Shader 结构 2011年04月24日 ... -
网上淘来的文章,对自己有点帮助
2012-01-19 10:13 712网上淘来的文章,对自己 ... -
英语的重要性
2012-01-19 10:13 501英语的重要性 2011年02月28日 英语的重要性 全球 ... -
背诵再背诵
2012-01-19 10:13 581背诵再背诵 2010年06月07 ... -
关于计算机图形学的学习资料建议
2012-01-17 02:54 765关于计算机图形学的学习资料建议 2010年07月03日 ... -
<<游戏是这样写成的>>(OpenGL ES,Objc++,MD2模型显示,粒子系统)
2012-01-17 02:54 911>(OpenGL ES,Objc++,MD2模型显示,粒 ... -
怎样用OpenGL在某一位置上写字符串?
2012-01-17 02:54 617怎样用OpenGL在某一位置上写字符串? 2011年11月2 ... -
Flash开发移动设备技巧
2012-01-15 22:32 503Flash开发移动设备技巧 ... -
photoshop CS3 脚本入门
2012-01-15 22:32 822photoshop CS3 脚本入门 2009年09月14日 ... -
AS3 编程易犯盲点――绝对对您有帮助,新手们都来看看吧
2012-01-15 22:32 669AS3 编程易犯盲点――绝对对您有帮助,新手们都来看看吧 2 ... -
flash复习2
2012-01-15 22:32 942flash复习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 类、...
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
我们在单片机开发中常会遇到需要将UTF-8转换为GBK编码的需求。在了解各种编码格式的情况下可知, UFT-8不能直接转成GBK,需中转成unicode再转换为gbk。而unicode和gbk之间没有算法可以直接计算,需要查表方式获取。 网上有一些C语言实现的代码,我这里分享一种microPython的实现代码 接下来就是要考虑表的存储方式了,刚开始我想着把表存到代码里直接通过索引实现编码转换。但是gb2312有七千多个字符全部存储要耗费很大内存,即使是32位的esp32也只有512k的内存,加上其他资源的消耗,剩余的内存不足以存储编码转换表。 于是只能将表保存成一个文件(转化成bin文件会比较好,方法类似),通过读写文件来减少内存开销。 具体的查表就是简单的二分法
基于VB实现的车队综合业务管理系统(论文+源代码) 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。
基于知识图谱的推荐算法-NCFG的实现 运行环境 python == 3.7.0 torch == 1.12.0 pandas == 1.1.5 numpy == 1.21.6 sklearn == 0.0 数据集介绍 music-音乐 book-书籍 ml-电影 yelp-商户 文件介绍 ratings.txt:记录用户点击的项目,1代表点击了,0代表没有点击 kg.txt:知识图谱文件,第一列是头实体,第二列是尾实体,第三列是关系 user-list.txt:用户及其id文件,第一列是用户的id,第二列是用户 其余文件可忽略
JAVA002打飞机游戏设计(程序+设计说明书).zip
Engineering_Electromagnetic_Theory_Lab_3.pdf
自己弄的基于matlab实现的多端直流配电网的仿真模型,是支撑自己小论文的东东。仿真环境是用的matlab。
课程设计,污水处理设计方案
DHT11温湿度传感器是一款高性能、低成本的数字温湿度复合传感器。它集成了温度感应和湿度感应功能,可以准确地测量环境中的温度和湿度,并通过数字信号输出数据。以下是关于DHT11温湿度传感器的详细介绍: DHT11传感器内部包含一个NTC热敏电阻用于温度测量和一个薄膜电容湿度传感材料用于湿度测量。NTC热敏电阻的电阻值会随着温度的变化而变化,DHT11通过测量电阻值的变化来计算环境的温度。而薄膜电容湿度传感材料的电容值则会随着湿度的变化而变化,DHT11通过测量电容值的变化来计算环境的湿度。 DHT11传感器具有高精度、高可靠性和稳定性好的特点。其湿度测量范围为20%RH至90%RH,精度可达±5%RH;温度测量范围为-20℃至+60℃,精度可达±2℃。传感器的工作电压范围为3.3V至5.5V,工作电流较小,功耗低。此外,DHT11传感器还具有超长的信号传输距离和超强的抗干扰能力,可以在复杂的环境中稳定工作。 DHT11传感器采用单总线数字信号传输方式,通过单个引脚进行数据输入和输出。它使用特定的时序信号来传输温度和湿度数据,主机可以通过解析这些时序信号来获取温度和湿度的数值。这种
污水处理
delphi家庭财务管理系统.zip
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
ASP+ACCESS网上人才信息管理系统(源代码+设计说明书).zip
ASP基于BS结构的工厂设备管理系统的设计与开发(源代码+设计说明书).zip
Node.js,简称Node,是一个开源且跨平台的JavaScript运行时环境,它允许在浏览器外运行JavaScript代码。Node.js于2009年由Ryan Dahl创立,旨在创建高性能的Web服务器和网络应用程序。它基于Google Chrome的V8 JavaScript引擎,可以在Windows、Linux、Unix、Mac OS X等操作系统上运行。 Node.js的特点之一是事件驱动和非阻塞I/O模型,这使得它非常适合处理大量并发连接,从而在构建实时应用程序如在线游戏、聊天应用以及实时通讯服务时表现卓越。此外,Node.js使用了模块化的架构,通过npm(Node package manager,Node包管理器),社区成员可以共享和复用代码,极大地促进了Node.js生态系统的发展和扩张。 Node.js不仅用于服务器端开发。随着技术的发展,它也被用于构建工具链、开发桌面应用程序、物联网设备等。Node.js能够处理文件系统、操作数据库、处理网络请求等,因此,开发者可以用JavaScript编写全栈应用程序,这一点大大提高了开发效率和便捷性。 在实践中,许多大型企业和组织已经采用Node.js作为其Web应用程序的开发平台,如Netflix、PayPal和Walmart等。它们利用Node.js提高了应用性能,简化了开发流程,并且能更快地响应市场需求。
埃森哲_组织设计的指导思想gl.ppt
卷积神经网络(Convolutional Neural Networks,CNN)是深度学习领域中一种非常重要的神经网络结构,特别适用于处理图像和视频数据。以下是关于卷积神经网络的500字资源介绍: 卷积神经网络是一类包含卷积计算的前馈神经网络,它的核心在于“卷积与池化”操作。在卷积层中,神经元仅与部分邻层神经元连接,这种局部连接和权值共享的特性使得卷积神经网络能够以较小的计算量学习格点化特征,如像素和音频,且稳定有效。 卷积神经网络的主要构成包括卷积层、池化层和全连接层。卷积层通过卷积核对输入图像进行特征提取,生成特征图;池化层则对特征图进行下采样,降低数据维度,同时保留重要信息;全连接层则负责将提取的特征进行整合,用于分类或回归任务。 卷积神经网络在计算机视觉领域具有广泛的应用,如图像分类、目标检测、人脸识别等。通过训练大量的图像数据,卷积神经网络能够自动学习图像的特征表示,比传统的手工设计特征方法更加有效。此外,卷积神经网络也被应用于自然语言处理、语音识别等领域,并取得了显著的成果。 总之,卷积神经网络是一种强大的深度学习模型,它通过模拟人类的视觉系统来处理图像和视频数据