AS3 - предварительный загрузчик иногда не загружает изображения или внешний SWF

Первый вопрос здесь; надеюсь, вы можете помочь. Я совершенно сбит с толку.

Я создал флэш-слайд-шоу с предварительной загрузкой изображений. После предварительной загрузки изображений он загружает внешний файл флэш-памяти, а затем изображения. Проблема в том, что очень и очень редко не удается загрузить изображения в поле зрения, и я просто увижу анимацию предварительной загрузки, но она все равно может загрузить внешний swf. Кроме того, он может сделать обратное и загрузить изображения, а не внешний SWF.

Последнее мне не удалось воспроизвести, хотя клиент несколько раз это замечал. Первое случается со мной, но очень редко.

Вот (я думаю) соответствующий код:

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 = [email protected]();

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);
  }
}

Активный сайт находится здесь: http://www.luxuryportfolio.com — посмотрите, сможет ли кто-нибудь из вас воспроизвести выше вопросы...

Спасибо!!


person Community    schedule 25.09.2009    source источник


Ответы (5)


Здесь важно отметить, что вы, скорее всего, вызываете эту проблему. Ваш код хорош, не поймите меня неправильно, но перебирать массив, создавать загрузчики и выполнять загрузку на каждой итерации — плохая идея. Следующее может представить проблемы, которые у вас возникли. Большинство людей, включая меня, используют бюджетный хостинг (лично BLUEHOST), который отлично подходит для того, чем он является, но, как правило, это общие ящики, и вы хотите оптимизировать загрузку своих сайтов. Обойти это довольно просто.

ОБЪЯСНЕНИЕ:

Вместо того, чтобы просто перебирать массив с помощью цикла for, который чертовски близок к мгновенному, мы изящно обработаем каждую загрузку отдельно; по завершении начнется следующий, пока массив, который мы используем в качестве поставщика данных, не станет пустым. При этом вам нужно создать функцию, чтобы начать загрузку первого и последующих изображений.

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.
}

С учетом вышеизложенного ваш сайт в любом случае должен загружаться быстрее, и он будет иметь хороший линейный эффект загрузки, слева направо, сверху вниз, или как бы вы ни программировали свои изображения для размещения.

ТАКЖЕ:

Вам необходимо прослушивать события асинхронных ошибок и перехватывать синхронные ошибки. Если и когда возникает ошибка, с этими обработчиками и некоторым интуитивно понятным кодом ваша галерея может сообщить себе, что произошла ошибка и в какой момент она произошла; Таким образом, он может просто начать загрузку с этого места, будь то резервное копирование числа и перезапуск для перебора массива.

Я не хочу, чтобы это было оскорбительным, потому что я действительно не знаю наверняка, но любой флеш-разработчик должен использовать отладчик Flash Player 10, и, кстати, такие вещи, как Firefox с firebug для http sniffing и т.д. обязательно, но в данном конкретном случае отладчик многое бы вам сказал.

Из живого следа вашего сайта я вижу несколько интересных предупреждений, которые, вероятно, также следует рассмотреть.

Удачи.

person Brian Hodge    schedule 26.09.2009

Проблема здесь:

    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]);

В конце этого блока созданный вами объект Loader выходит за пределы области видимости; на него ничего не ссылается, поэтому он подходит для сборки мусора, т. е. в какой-то момент (непредсказуемо) проигрыватель Flash очистит память, выделенную для этого объекта.

В большинстве случаев GC какое-то время не срабатывает, поэтому ваша загрузка, вероятно, будет работать. Но иногда срабатывает GC, и вы теряете некоторые из этих объектов загрузчика.

Так что - держитесь за свои погрузчики! Сохраните их в другом массиве (рядом с вашим массивом images будет хорошо), а затем очистите их после того, как COMPLETE сработает для каждого из них.

Кроме того, всегда лучше сделать так:

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));

а не это:

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); 

потому что в некоторых случаях, когда файл загрузки кэшируется, COMPLETE сработает до того, как вы добавите свой слушатель! Убедитесь, что вы добавили слушателей перед запуском операции, которая может запускать события во всех ситуациях. Надеюсь это поможет!

person IanT    schedule 29.09.2009
comment
Да, еще одно замечание: Брайан прав, что Flash может захлебнуться, если вы загрузите слишком много файлов одновременно, а в некоторых крайних случаях даже приведет к сбою браузера (у меня это было часто в AS2); часто лучше ставить их в очередь, как он предлагает, хотя на практике мы обнаружили, что одновременная загрузка 5-10 — это нормально. - person IanT; 29.09.2009
comment
да, слушатели перед загрузкой. Всегда будьте готовы. :) - person Brian Hodge; 01.10.2009

У меня не было проблем с просмотром вашей (красивой) галереи. Вы пытались добавить обработчик ошибок в свой загрузчик?

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

Если вы пытаетесь отследить прерывистую ошибку, ваш первый шаг — зарегистрироваться для событий обработки ошибок, которые может запускать загрузчик. Ваш загрузчик, вероятно, испытывает периодические ошибки связи с сервером или что-то в этом роде, и эти предупреждения просто падают в черную дыру, поэтому вы видите это неустойчивое поведение.

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

person JStriedl    schedule 25.09.2009

Другим решением может быть использование QueueLoader от Hydrotik. Посмотри:

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

Работает как шарм для меня. Удачи.

Кстати: у кого-нибудь есть какие-либо проблемы с обновлением, когда флеш-плеер не запускает ПОЛНУЮ загрузку в IE7? :)

person Ben    schedule 10.12.2009