Adobe
产品
Acrobat
创意套装
Digital Marketing Suite
Digital Publishing Suite
Elements
Photoshop
Touch Apps
更多产品
解决方案
数字营销
数字媒体
教育
金融服务业
政府部门
网页体验管理
更多解决方案
学习帮助下载公司
商店
在线商店
批量许可
查找经销商
搜索
 
信息 登录
欢迎,我的支持
我的帐户
注销
为何登录?登录后可以管理您的帐户,访问试用版下载、产品扩展和社区区域等。
Adobe
产品 分类   搜索  
解决方案 公司
帮助 学习
登录 欢迎, 我的货物 我的支持
Qty:
Subtotal
Checkout
Adobe 开发者中心 / Flash 开发人员中心 /

Flash务实主义(六)——Loading

作者 flashyiyi

flashyiyi
  • 个人空间

Content

  • 加载形式
  • 资源打包成 SWF
  • 资源分散加载

创建日期

26 May 2011

页面工具

在 Facebook 上共享
在 Twitter 上共享
在 LinkedIn 上共享
书签
打印

要求

用户级别

中级

加载形式

FLASH 加载文件有两种常规方式:一种是 URLLoader,可以加载文本、二进制数据或 URL 编码变量形式的数据,然后转换成简单的文本形式或值对字符串形式;一种是 Loader,可以将加载的图像文件转换成 BitmapData,也可以解析 SWF 文件。(Socket, LocalConnection 这些非常用类不在讨论范围)

加载的资源应被统一管理以方便调用和重用,管理方式一般有两种:一种是将资源全部打包进 SWF;一种是加载分散资源通过配置进行管理。我将对这两种管理方式进行介绍。

资源打包成 SWF

在编辑 FLA 文件时,我们可以导入各种图片,并为其设置链接名。除手工逐个操作外,我们可以借助 JSFL 进行自动化处理(请参考http://bbs.9ria.com/thread-31730-1-1.html)。

由此生成 SWF 后,再用 Loader 加载。这时候我们需要的不再是舞台上的内容,而是 SWF 应用域里包含资源的类。可以用 Loader 的 contentLoaderInfo.applicationDomain.getDefinition() 方法来获得这个类,并实例化。如果在执行加载方法时第二个参数 LoaderContext 设置成了 ApplicationDomain.currentDomain,使得被加载的 SWF 与主 SWF 共享同一应用域,那么直接使用 getDefinitionByName () 方法也可以获得这个类。

通过 new 的方式就可以实例化获得的 BitmapData 或 MovieClip 类,然后使用。因此项目中要想得到一个资源,只要知道它的链接名即可。链接名是自行设定的有意义的名字,完全可以当做资源的唯一 ID。

需要注意的是,new 的过程就是图片解压缩的过程。处于 Class 状态时,图片占用的内存和 SWF 文件中这个图片占用的磁盘空间一致,而一旦通过 new 解压成无压缩的 BitmapData 后,占用的内存会急剧增加。不管是 PNG、JPG,还是矢量动画,new 之后的体积都会比原来大得多,因此不要随便将资源实例化后暂存。这个实例化过程理所当然是比较费时的,可能会出现卡的现象,但预先实例化,内存占用上是有很大区别的。

此外,如果选择设置 LoaderContext 使得全部资源加载到同一个域的话,有冲突的链接名是以先来先到的原则处理,即如果两个资源链接名相同,以先加载的对象为准。

打包成 SWF 有一个优点,SWF 可以让 JPEG 支持透明通道。一般来说,JPEG 压缩率高而不支持透明通道,PNG 压缩率低支持透明通道。将 PNG 导入 FLA 然后设置成 JPEG 压缩后,就能在压缩的同时保留透明通道,可以让支持透明通道的图片体积大大减小。

打包成 SWF 后,加载快且易于管理,是推荐方式。但这种做法限定你必须一次性加载所有资源,不能按需加载,有一定的局限性。比较适合加载 UI 皮肤,以及需要立即显示的图标等等。

还有一点需要注意:SWF 舞台上的内容,即使不显示出来也会消耗资源,因此请务必保证在发布时舞台为空。

资源分散加载

如果文件要按需加载,或者不希望用 SWF 打包增加维护成本,或者有大量文本以致于不能用 FLA 导入,那我们只能逐个文件加载。

因为资源可能处于不同目录,命名也不规范,也会有扩展名,这样的路径在代码中作为 ID 存在是不合适的。所以一般都会有一个文本配置文件,将这些文件路径和一个名称对应起来,并提供给模块加载。加载完成后则是通过这个名称来获取资源。

不要直接用 Loader 加载文件

不同文件有不同的加载方式,文本和二进制文件只能通过 URLLoader 加载,而 PNG、JPG、SWF 等文件则可以通过 Loader 和 URLLoader 两种方式加载。如果资源需要长期保存,建议全部用 URLLoader 方式加载,在需要获取资源时,再通过 Loader 的 loadBytes 方法解析已经加载的二进制数据,之后再显示。

这样做目的是为了节省内存,因为 Loader 加载的资源会自动实例化(解码),PNG、JPG 会展开成无压缩的 BitmapData,SWF 舞台的内容也会全部实例化,他们会占用大量内存。先用 URLLoader 将他们作为二进制数据加载,需要时再解码实例化,就不会出现这个问题。

并发加载

多文件加载还有一个问题:浏览器对并发下载数有限制,而这个限制和 Flash Player 的机制有冲突,所以一般情况下 Flash Player 同时发起的加载请求数最好不要超过5个, 否则加载事件可能会失效。为了解决这个问题,大部分人的解决方案都是采取队列加载,一次只加载一个文件。这在文件数量较小、单文件体积较大时并没有问题,但是当文件数量多、单文件体积小时,由于每次加载完一个文件后,重新请求下一个文件时需要等待服务器响应一段时间才开始加载,这样会浪费很多带宽,文件数量多时这个缺陷不能忽略,最多可能消耗2至3倍的加载时间。

为了解决这个问题,我们需要一种特殊的队列加载模块,可以同时加载,但是同时加载的文件数量不能超过某个值。基本思路就是在加载完一个文件后,检查正在进行加载的文件数量,小于定值就取队列中的下一个地址新建加载,否则就什么都不做。

BulkLoader(http://code.google.com/p/bulk-loader),

LoaderMax(http://www.greensock.com/loadermax)

都提供了这个功能,当然我的GhostCat也通过 AssetManager(复合 QueueLoadOper 实现)提供了这个功能。复杂度实际上并没有比线性加载高多少。

这样做,加载时等待服务器返回时依然有文件在下载,多个加载过程会平衡消耗带宽,带宽就不会被浪费。一般同时加载数量为2就足够了。但如果你的文件特别零散,使得两个文件同时等待返回的几率也很高,也可以考虑设置2以上的值。

哈希表缓存

当加载文件数量特别大的时候(诸如数百个),注意不要只使用数组保存。你可以创建一个 Dictionary,然后将名称作为键加载内容作为值,做一个哈希表,以后都直接通过名称从这个哈希表取值,会比遍历数组查找名称快很多。

使用 ZIP 或其他打包形式

如果你不喜欢 SWF 这种打包方式,也可以选择 ZIP 打包,详情请阅读http://nochump.com/blog/archives/15。

ZIP 的优点是可以用 winrar 打开,不需要借助专门的工具,缺点则是解压需要时间。当然,你也可以考虑用二进制自定义一个封装格式,这样也能加密资源文件,但这需要你自己编写一个管理工具。当然,这也不算特别麻烦。

使用 ShareObject 缓存

虽然有浏览器缓存,但实际上这种缓存持续不了几天,因为浏览器一向都有最大缓存限制。一般你看几个视频,这个缓存空间就消耗得差不多了。为了不让 Flash 加载的文件缓存被冲洗掉,你可以将加载的文件的二进制数据(Loader 是 contentLoaderInfo.bytes,URLLoader 则要用二进制方式加载获取其 data 属性)保存在 ShareObject 里,并添加版本号以便更新,下次加载就直接取这个数据。这个操作会请求大量 ShareObject 空间,因此 FLASH 会弹出提示让用户确认。如果你担心用户不确认,可以在游戏其他地方向用户说明情况并要求他们点击确认按钮。

现在不少游戏都采用了这种做法,效果还是可以的。

显示总体加载进度

我们可能在开始时会加载多个文件。比起每加载一个文件显示一次进度条从0%到100%的过程,显然是显示所有文件总体的加载进度,只进行一次从0%到100%的过程更具有实际意义。但是 FLASH 做这件事情并不太容易,因为它想要获得一个文件的大小就必须去加载它,而这个加载需要时间,你没有办法从一开始就立即获得所有文件的大小。

实现的方法只有一个,就是在程序中或者配置中写死所有文件的总大小,然后根据所有文件已经加载字节数的总和来计算和显示进度。

至于这个总和如何获得,可以在程序中写上 trace,实际加载运行一次便能获得实际所有文件大小总和,也可以做专门工具计算,也可以用操作系统来直接查看总和,总之方法不是问题。而且,即使这个值不准确也无大碍,因为加载流程依然是按加载完所有文件作为依据,而这个进度只是用来显示,就算不准也不过是未到100%就结束或者到了100%也要等待一段时间才能结束。这无伤大雅。

之前所说的类库都提供了这样的功能。

主 SWF 加载问题

SWF 必须加载完所有类后才能开始运行并显示图像,这样一来,第一个主 SWF 加载自己时就无法显示加载进度。解决这个问题有两种办法:

一种办法很老但是实用,就是创建一个小 SWF 先显示出来,专门用来加载主 SWF,主 SWF 加载完毕后它就完成了使命。实际上这并不麻烦也是最稳定的一种方案。

另一种方式是利用 Frame 元标签。在主 SWF 类名上面添加

[Frame(factoryClass="加载类类名")]

即可指定一个类作为加载类,它会在主 SWF 未加载完之前显示。这个类是一个两帧 MovieClip,当它自己加载完毕后,就可以反射出主 SWF 的内容并实例化。

可以看这篇文章:http://www.bit-101.com/blog/?p=946。

而我自己的加载类模板则是这个,可以作为参考:

http://code.google.com/p/ghostcat/source/browse/trunk/GhostCat/src/ghostcat/util/load/RootLoaderBase.as

Flash User Forum

More
02/21/2012 sound activated movie
02/21/2012 How do I disable a button once it's pressed?
02/21/2012 Ipad only publish
02/21/2012 Problems with symbols in CS5.5 when using CS5 doc

Flash Cookbooks

More
02/13/2012 Randomize an array
02/11/2012 How to create a Facebook fan page with Flash
02/08/2012 Digital Clock
01/18/2012 Recording webcam video & audio in a flv file on local drive

产品

  • Adobe Touch Apps
  • Acrobat
  • Creative Suite
  • Digital Marketing Suite
  • Digital Publishing Suite
  • Elements
  • 移动应用程序
  • Photoshop

解决方案

  • 数字营销
  • 数字媒体
  • 网页体验管理

行业

  • 教育
  • 金融服务业
  • 政府部门

帮助

  • 产品帮助中心
  • 订货和退货
  • 下载和安装
  • 我的 Adobe

学习

  • Adobe 开发人员连接
  • Adobe TV
  • 培训和认证
  • 论坛
  • 设计中心

购买方式

  • 在线商店
  • 批量许可
  • 查找经销商

下载

  • Adobe Reader
  • Adobe Flash Player
  • Adobe AIR
  • Adobe Shockwave Player

公司

  • 新闻编辑室
  • 合作伙伴计划
  • 公司社会责任
  • 工作机会
  • 投资者关系
  • 事件
  • 法律
  • 联系 Adobe
选择您的地区 中国(更改)
选择您的地区 关闭

North America

Europe, Middle East and Africa

Asia Pacific

  • Canada - English
  • Canada - Français
  • Latinoamérica
  • México
  • United States

South America

  • Brasil
  • Africa - English
  • Belgium - English
  • Belgique - Français
  • België - Nederlands
  • България
  • Česká republika
  • Danmark
  • Eastern Europe - English
  • Eesti
  • España
  • France
  • Deutschland
  • Hrvatska
  • Ireland
  • Israel - English
  • Italia
  • Latvija
  • Lietuva
  • Luxembourg - Deutsch
  • Luxembourg - English
  • Luxembourg - Français
  • Magyarország
  • Middle East and North Africa - English
  • Moyen-Orient et Afrique du Nord - Français
  • Nederland
  • Norge
  • Österreich - Deutsch
  • Polska
  • Portugal
  • România
  • Россия
  • Schweiz - Deutsch
  • Suisse - Français
  • Svizzera - Italiano
  • Slovenija
  • Slovensko
  • Srbija
  • Suomi
  • Sverige
  • Türkiye
  • Україна
  • United Kingdom
  • Australia
  • 中国
  • 中國香港特別行政區
  • Hong Kong S.A.R. of China
  • India - English
  • 日本
  • 한국
  • New Zealand
  • 台灣

Southeast Asia

  • Includes Indonesia, Malaysia, Philippines, Singapore, Thailand, and Vietnam - English

Copyright © 2012 Adobe Systems Incorporated。保留所有权利。

使用本网站表明您同意使用条款和在线隐私政策。

京 ICP 备 10217899 号 京公网安备 110105010404