(转载)http://blog.dou.li/flash-loader%E5%8A%A0%E8%BD%BD%E5%AE%8C%E6%88%90%E4%B8%8D%E5%8F%91%E9%80%81complete%E5%92%8Cerror%E4%BA%8B%E4%BB%B6%E7%9A%84%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90.html

Flash进行资源加载时常会“停住”,表现为加载进度卡在某个地方。跟踪发现Loader的progress为100%,但未发送Event.COMPLETE或IOErrorEvent.IO_ERROR等事件。

目前项目加载底层的队列依赖于Loader(URLLoader)的COMPLETE和ERROR事件,如果这两个事件不发送将导整套加载机制崩溃 – -,后续跟踪发现的确会如此。

问题展示

以下给出一个Demo,可重现Loader加载到100%但不会发送Event.COMPLETE或IOErrorEvent.IO_ERROR等事件的问题:

package
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.HTTPStatusEvent;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.net.URLRequest; public class CheckFailSWFLoad extends Sprite
{
public function CheckFailSWFLoad()
{
var load:Loader = new Loader();
load.contentLoaderInfo.addEventListener(Event.COMPLETE, onEvent);
load.contentLoaderInfo.addEventListener(Event.INIT, onEvent);
load.contentLoaderInfo.addEventListener(Event.OPEN, onEvent);
load.contentLoaderInfo.addEventListener(Event.UNLOAD, onEvent);
load.contentLoaderInfo.addEventListener(HTTPStatusEvent.HTTP_STATUS, onEvent);
load.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onEvent);
load.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, onProgress); load.load(new URLRequest("a.swf"));
} private function onEvent(e:Event):void
{
trace(e.type);
} private function onProgress(e:ProgressEvent):void
{
trace(e.type + ":" + e.bytesLoaded + "/" + e.bytesTotal);
}
}
}
执行结果:
open
progress:0/524216
progress:8192/524216
progress:16384/524216
progress:24576/524216 这里省略若干条……
progress:507904/524216
progress:516096/524216
progress:524216/524216

如上,对Loader的所有网络相关事件进行监听,只有Event.OPEN和ProgressEvent.PROGRESS事件有响应,progress达100%时无后续输出。

附上一个正常的加载输出:

open
progress:0/75744
progress:8192/75744
progress:16384/75744
progress:24576/75744
progress:32768/75744
progress:40960/75744
progress:49152/75744
progress:57344/75744
progress:65536/75744
progress:73728/75744
progress:75744/75744
init
httpStatus
complete

正常的加载最终会抛出Event.COMPLETE事件的。

原因分析

这所以导致面结果是因为,a.swf文件是一个已损坏的文件,要么与原文件大小不等、要么大小一到致但数据错误,都会导致以上问题。有兴趣可以拿个.swf文件改一下内容试试。

如果工程运行在浏览器中,由于浏览器的Cache,一次加载失败后会在Cache中留下损坏的文件。此时,就算是刷新再进,浏览器不会从Server端获取文件,将继续得到Cache中的坏数据。

用URLLoader有没有问题呢?

我们用的Loader作测试,经试验用URLLoader无问题,因为URLLoader只关注文件本身,照原样将文件下载下来(把URLLoader.dataFormat 设为URLLoaderDataFormat.BINARY)。而Loader是显示对象,除加载外还会将加载的数据转为DisplayObject,以至其加载不再纯粹。

但对于加载一个swf最终作为DisplayObject可有两种方案:

  1. 用Loader加载后使用;
  2. 用URLLoader加载得到ByteArray,再用Loader加载ByteArray得到DisplayObject;

两种方案在Loader这一步都会出现这个问题。

加载损坏的图像有没有问题呢?

经试验,加载一张损坏的图片,Loader能正常发送Error事件。

解决方案

private function onProgress(e:ProgressEvent):void
{
if(e.bytesTotal != realSize)
reload();
}

记录需要加载的资源真实大小,加载时判断加载的bytesTotal是否与记录的大小一致,不一致则判定文件已损坏,发起重载。

对于上面说的浏览器Cache问题,解决方案有3:

  1. 引导用户手动去清浏览器Cache;
  2. 重载时让你的URL发生改变,加个可变参数,如:http://domain/a.swf?v=143,这个143在重载时换一个值;
  3. 摈弃浏览器Cache,自己用SharedObject构建Cache,加载URL全用随机参数(v的值每次改变),发现坏数据清掉SharedObject对应数据就行;

转载请注明:兜·里 » Flash Loader加载完成不发送COMPLETE和ERROR事件的问题分析

(转载)Flash Loader加载完成不发送COMPLETE和ERROR事件的问题分析的更多相关文章

  1. as3 Loader 加载资源后内存泄露无法释放的问题。

    本人用Loader加载外部一个swf.之后unloadAndStop,Flash概要分析发现,内存没有被释放. 网上搜了一大堆文章,要么就是加载bitmapdata之后,自己dispose,要么就是加 ...

  2. Loader加载器

    今天学到了这个Loader,浅谈一下自己的看法: 1.定义 Loader是一个加载器,可以用来它访问数据,可以看做访问数据的机器(好比挖掘机).装再器从android3.0开始引进,它使得在activ ...

  3. [ActionScript 3.0] AS3.0 Loader加载子swf时是否需要指定新的应用程序域ApplicationDomain

    实际应用中, Loader加载子swf时是否需要指定新的应用程序域ApplicationDomain,需要择情况而定. 1.如果在本地将项目位置添加到flashplayer受信任位置(上一篇文章所述) ...

  4. [转载] Android动态加载Dex机制解析

    本文转载自: http://blog.csdn.net/wy353208214/article/details/50859422 1.什么是类加载器? 类加载器(class loader)是 Java ...

  5. QML之使用Loader加载QML组件

    呵呵,今晚是边看<裸婚时代>边敲代码,那电影看得...!钱真他妈不是个东西. 盼望Meego火起来. QML的Loader元素经常备用来动态加载QML组件.可以使用source属性或者so ...

  6. 【转载】浏览器加载和渲染html的顺序

    1.浏览器加载和渲染html的顺序 1.IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的.2.在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素 ...

  7. 解决swfupload改变display属性后flash重新加载的问题(chome,safari内核的所有浏览器)

    最近在做的项目中有要用到上传控件,所有就用到了swfupload flash上传控件 因为在项目中要使用到Tab控件,tab控件通过改变display属性来控制tab页的显 示与隐藏.当swfuplo ...

  8. 操作系统开发系列—12.c.从Loader加载ELF内核,顺便解释下函数调用过程 ●

    实际上,我们要做的工作是根据内核的Program header table的信息进行类似下面这个C语言语句的内存复制: memcpy(p_vaddr, BaseOfLoaderPhyAddr+p_of ...

  9. [转载]Android 异步加载解决方案

    2013-12-25 11:15:47 Android 异步加载解决方案,转载自: http://www.open-open.com/lib/view/open1345017746897.html 请 ...

随机推荐

  1. iOS开发——真机调试证书—发布证书

    (最近准备考试,空闲整理成博客……)

  2. bzoj1260[CQOI2007]涂色paint

    思路:区间dp,用f[i][j]表示区间[i,j]的答案,然后转移即可. #include<iostream> #include<cstdio> #include<cst ...

  3. Linux网络应用编程之集线器(Packet Tracer仿真)

    Packet Tracer入门 一,集线器概况 对接收到的信号进行再生整形放大,以扩大网络的传输距离,同时把所有节点集中在以它为中心的节点上. 工作于OSI(开放式系统互联参考模型)的最底层(物理层) ...

  4. IE6 png 透明 (三种解决方法)

    FF和IE7已经直接支持透明的png图了,下面这个主要是解决IE6下透明PNG图片有灰底的 ====================================================== ...

  5. nginx服务器的日志太多:定期执行脚本删除

    #!/bin/bash -type f -name *.log | xargs rm -f 脚本名字autodellog.sh 设置定时器(每天凌晨一点执行) [root@localhost ~]# ...

  6. simplexml 使用实例

    搞了几天php处理xml文件,终于有点头绪,记录下来分享一下.simplexml 是php处理xml文件的一个方法,另一个是dom处理,这里只说simplexml.目前php处理xml用的比较多,比较 ...

  7. Linux下find指令

    Linux是一个“一切皆文件”的操作系统,find(查找文件)指令就尤为重要了.find命令在目录结构中搜索文件,并执行指定的操作. 1.命令格式: find pathname -options [- ...

  8. CSS3 calc() 会计算的属性

    calc是英文单词calculate(计算)的缩写,是css3的一个新增的功能,你可以使用calc()给元素的border.margin.pading.font-size和width等属性设置动态值. ...

  9. 最简单的CRC32源码-查表法

    这个算法是在逐BYTE法的基础上进行修改的,在上一篇文章里我们说过,如果不查表的话,逐BYTE法和逐BIT法没什么区别,现在我们就把这个算法写出来,注意在调用CRC校验函数前需要先调用表生成函数: u ...

  10. 【java并发】线程同步工具Semaphore的使用

    Semaphore通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,我们可以自己设定最大访问量.它有两个很常用的方法是acquire()和release(),分别是获得许可和释放许可.  官方J ...