简体   繁体   English

AS3-预加载器有时不会加载图像,也不会加载外部SWF文件

[英]AS3 - preloader occasionally won't load images, or external swf

First question here; 这里的第一个问题; hope you can help. 希望能对您有所帮助。 I'm completely flummoxed. 我完全被弄糊涂了。

I created a flash slideshow which preloads the images. 我创建了一个Flash幻灯片演示,可以预加载图像。 After preloading the images, it proceeds to load an external flash file and then the images. 预加载图像后,它将继续加载外部Flash文件,然后加载图像。 The problem is, very very occasionally, it will fail to actually load the images into view, and I'll just see the preloading animation, but it might still load the external swf. 问题是,在非常偶然的情况下,它实际上无法将图像加载到视图中,而我只会看到预加载的动画,但是它仍然可以加载外部swf。 Additionally, it might do the reverse, and load the images and not load the external swf. 此外,它可能做相反的操作,并加载图像而不加载外部swf。

I have no been able to reproduce the latter, although the client has noticed it on a few occasions. 我无法重现后者,尽管客户已经几次注意到它了。 The former will happen for me, but only very rarely. 前者会为我发生,但很少发生。

Here is the (I think) relevant code: 这是(我认为)相关代码:

function onXMLLoadComplete(e:Event):void {
// create new xml with the received data
xmlSlideshow = new XML(e.target.data);
// get total slide count
// misc xml data
info_holder.mcInfo.lbl_tagline.text = xmlSlideshow.misc.@tagline;
info_holder.mcInfo.goToUrl_btn.lbl_view.text = xmlSlideshow.misc.@view.toUpperCase();

intSlideCount = xmlSlideshow..img.length();
//trace(intSlideCount);
imageArray = new Array(intSlideCount);

for (var i:int = 0; i < intSlideCount; i++) {
    //imageArray[i] = new URLRequest(xmlSlideshow..img[i].@src);    
    var loader:Loader = new Loader();
    loader.load(new URLRequest(xmlSlideshow..img[i].@src));
    //trace(xmlSlideshow..img[i].@src);
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete); 
    //loader.load(imageArray[i]);
  }
}

function onImageLoadComplete(e:Event):void {

if (++numberOfImagesLoaded == intSlideCount) {
    // animate the info bar and then
    //trace(intSlideCount);
    //trace(numberOfImagesLoaded);
    info_holder.play();
    // switch the first slide without a delay   
    // reset index of images
    //load map div via jQuery
    if (ExternalInterface.available) {
        ExternalInterface.call('openMap');
    }
    intCurrentSlide = -1;
    switchSlide(null);
  }
}

The live site is here: http://www.luxuryportfolio.com - see if any of you can reproduce the above issues... 实时站点在这里: http : //www.luxuryportfolio.com-看看是否有人可以重现上述问题...

Thanks!! 谢谢!!

An important thing to note here is that you are most likely causing this issue. 这里要注意的重要事情是最有可能导致此问题。 Your code is good, don't get me wrong, but it is a bad idea to iterate through an array and create loaders and load on each iteration. 您的代码不错,不要误会我的意思,但是遍历数组并创建加载器并在每次迭代中加载都是一个坏主意。 The following can introduce the problems you're having. 以下内容可以介绍您遇到的问题。 Most people, including myself, use budget hosting (BLUEHOST personally), which are great for what they are, but are typically shared boxes and you want to optimize how your sites load. 包括我自己在内的大多数人都使用预算托管(个人为BLUEHOST),这很适合他们的需求,但通常是共享框,您想优化网站的加载方式。 The way around this is quite simple. 解决这个问题的方法非常简单。

EXPLANATION: 说明:

Instead of just iterating through an array with a for loop which is damn near to instant, we will gracefully handle each load by themselves; 我们将不仅仅通过遍历即时的for循环遍历数组,还可以自行处理每个负载。 upon completion the next will start, until the array we are using as the dataprovider is empty. 完成后,下一个将开始,直到我们用作dataprovider的数组为空。 That being said, you need to create a function to start loading the first and following images. 就是说,您需要创建一个函数来开始加载第一张和第二张图像。

private var images:Array = ["image1.jpg", "image2.jpg"];

private function _loadImage():void
{
    var loader:Loader = new Loader();
    var req:URLRequest = new URLRequest(images.shift()); //Removes and returns first element in an array.
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE. _onImageComplete);
}

private function _onImageComplete(e:Event):void
{
    var bmp:Bitmap = e.target.content as Bitmap;
    _someContainer.addChild(bmp);
    if(images.length > 0) _loadImage(); //Calls _loadImage function until array is empty.
}

With the above, your site should actually load faster anyhow, and it will have a nice linear effect to the load, left to right, top to bottom, or however your program your images to lay out. 有了以上内容,您的网站实际上无论如何应该加载得更快,并且对加载有很好的线性效果,从左到右,从上到下,或者您的程序可以对图像进行布局。

ALSO: 也:

You need to listen for asynchronous error events and catch synchronous errors. 您需要侦听异步错误事件并捕获同步错误。 If and when an error occurs, with these handlers in place, and some intuitive code, your gallery can let itself know that there was an error and at which point the error took place; 如果并且当发生错误时,只要有了这些处理程序以及一些直观的代码,您的图库就可以让自己知道发生了错误,并在错误发生的那一点; This way it can merely start loading from that place, whether it be backing up a number and restarting to iterate through an array. 这样,它就只能从该位置开始加载,而不管它是备份一个数字并重新开始遍历数组。

I do not intend this to be insulting, because I really don't know for sure, but any flash developer should be using the Flash Player 10 Debugger, and on a side note, things like Firefox with firebug for http sniffing and etc. are musts, but in this particular case, the debugger would have told you much. 我不希望这是侮辱性的,因为我确实不确定,但是任何Flash开发人员都应使用Flash Player 10调试器,并且附带说明一下,诸如Firefox和Firebug的HTTP嗅探之类的功能都是可以使用的。必须,但在这种特殊情况下,调试器会告诉您很多信息。

From a live trace of your site I see some interesting warnings that should probably be addressed as well. 从您的网站的实时跟踪中,我看到了一些有趣的警告,这些警告也可能会得到解决。

Good luck. 祝好运。

The problem's here: 问题在这里:

    var loader:Loader = new Loader();
    loader.load(new URLRequest(xmlSlideshow..img[i].@src));
    //trace(xmlSlideshow..img[i].@src);
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete); 
    //loader.load(imageArray[i]);

At the end of this block, the Loader object you've created goes out of scope; 在该代码块的末尾,您创建的Loader对象超出范围。 nothing is referring to it, so it's eligible for garbage collection ie at some point (unpredictably) the Flash player will clear up the memory allocated for that object. 没有东西在引用它,因此它可以进行垃圾回收,即,在某个时刻(不可预知),Flash Player将清除为该对象分配的内存。

Most of the time, GC won't kick in for a while, so your load will probably work. 在大多数情况下,GC不会启动一段时间,因此您的负载可能会起作用。 But sometimes, GC will kick in, and you'll lose some of those loader objects. 但是有时,GC会启动,您将丢失其中一些加载程序对象。

So - hang on to your loaders! 所以-挂到您的装载机上! Store them in another array (alongside your images array would be fine) and then clean them up after COMPLETE has fired on each one. 将它们存储在另一个数组中(与您的images数组一起就可以了),然后在对每个对象执行COMPLETE后清理它们。

As an aside, it's always better to do this: 顺便说一句,这样做总是更好:

var loader:Loader = new Loader();
// Note the position of this line!
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete); 
loader.load(new URLRequest(xmlSlideshow..img[i].@src));

rather than this: 而不是这样:

var loader:Loader = new Loader();
loader.load(new URLRequest(xmlSlideshow..img[i].@src));
// Note the position of this line!
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoadComplete); 

because in some cases where the loading file is cached, COMPLETE will fire before you've added your listener! 因为在某些情况下缓存了加载文件,所以在添加侦听器之前, COMPLETE将触发! Make sure you add your listeners before you start the operation which might fire events, in all situations. 开始操作之前,请确保在所有情况下都添加了侦听器这可能会引发事件。 Hope this helps! 希望这可以帮助!

I had no problem viewing your (pretty) gallery. 查看您的(漂亮)画廊我没有问题。 Have you tried adding an error handler to your loader? 您是否尝试过将错误处理程序添加到加载程序?

loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, onError);
function onError(e:IOErrorEvent) {
    trace("Catch error in a log file")
}

If your trying to track down a intermittent bug, your first step is to register for the error handling events that Loader can fire. 如果您尝试查找间歇性错误,则第一步是注册Loader可能引发的错误处理事件。 Your loader is probably experiencing periodic communication errors with the server or somesuch, and those alerts are just falling into a black hole, so your seeing this erratic behaviour. 您的加载程序可能与服务器等发生定期通信错误,并且这些警报正陷入一个黑洞,因此​​您会看到这种不稳定的行为。

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Loader.html#load%28%29 http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/display/Loader.html#load%28%29

http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/IOErrorEvent.html http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/IOErrorEvent.html

Another solution might be to use QueueLoader by Hydrotik. 另一个解决方案可能是使用Hydrotik的QueueLoader。 Take a look: 看一看:

http://code.google.com/p/queueloader-as3/ http://code.google.com/p/queueloader-as3/

Works like a charm for me. 对我来说就像一个魅力。 Good luck. 祝好运。

BTW: anyone have any of those refresh issues with the flash player not firing a load COMPLETE in IE7? 顺便说一句:有人在Flash播放器没有触发IE7中的“加载完成”时遇到任何刷新问题吗? :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM