flex 4 — ожидание завершения загрузки без зависания

#image #flex4

#изображение #flex4

Вопрос:

Мне было интересно, можно ли реализовать какую-либо логику, позволяющую завершить загрузку изображения без зависания.

Ради моего приложения я создал класс, который принимает URL-адрес изображения в конструкторе и загружает mx.controls.Изображение с использованием функции «load ()».

Смотрите класс ниже

 package com
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.*;
//import flash.net.URLRequest;

import mx.controls.Alert;
import mx.controls.Image;
//import mx.utils.OnDemandEventDispatcher;

public class SpriteImage extends Sprite
{
    //Pass the source path or url here.
    private var imageUrl:String;
    private var ready:int = -1;
    private var img:Image;

    public function SpriteImage(imgUrl:String)
    {
        //imageUrl = imgUrl;
        loadImage(imgUrl);
    }
    private function loadImage(imgUrl:String):void
    {

        img = new Image();
        img.addEventListener(Event.COMPLETE,onCompleteHandler);
        img.addEventListener(IOErrorEvent.IO_ERROR,onErrorHandler);     
        //img.source = imgUrl;
        img.load(imgUrl);

    }

    private function onCompleteHandler(e:Event):void{

        img.x = -(img.width/2);
        img.y = -(img.height/2);
        this.addChild(img);
        ready = 1;
    }

    private function onErrorHandler(e:IOErrorEvent):void
    {
        ready = 0;
        //Alert.show("Can't load :"   e.toString());
    }

    public function prepare():Boolean{

        while(ready == -1){
            trace(0);
        }           
        return ready;
    }
}

}
  

Теперь я использую этот класс из основного приложения следующим образом

 var img:SpriteImage = new SpriteImage(e.imageUrl);
img.prepare(); // just waits till image is loaded but freezes
var obj:DisplayObject = img;
  

Теперь проблема в том, что приложение никогда не выходит из метода prepare(). Это замораживает браузер, и я должен отключить процесс плагина, чтобы разморозить приложение.

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

Комментарии:

1. Ответ Антона в правильном направлении. Одна вещь, которую Flash сделал правильно, — это принудительное выполнение асинхронных внешних вызовов, что означает, что для правильного выполнения программы необходимо использовать обратные вызовы / прослушиватели событий, и это то, что гарантирует (или, по крайней мере, побуждает программиста реализовывать таким образом), что пользовательский интерфейс будет отзывчивым. Лично я обнаружил, что лекция Дуга Крокфорда о циклировании была поучительной относительно того, почему это на самом деле хорошо, а не просто произвольно задуманный шаблон, который раздражает.

Ответ №1:

Мне кажется, что вы сами создаете замораживание с помощью этого while (ready == -1) Почему бы вам просто не отключить возможность для пользователя идти дальше по вашим «шагам», пока изображение не будет загружено?

Вам не нужно синхронно ждать загрузки изображения, как вы делаете сейчас. Как только изображение будет загружено, вы получите уведомление о событии complete, которое отправляет его загрузчик. Затем вы можете включить все, что зависит от загружаемого изображения.

Один из простых способов — привязать свойство enabled элементов управления навигацией в вашем приложении к логическому свойству. Например, в вашем SpriteImage добавьте

 [Bindable] public var isImageLoaded:Boolean = false;
  

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

Blaze

Комментарии:

1. Ваш код разбил мой flash builder 2 раза.. пожалуйста, переосмыслите свой способ выполнения того, что вы пытаетесь сделать, учитывая мой ответ.

2. Спасибо за ответ, Блейз. Если вы видите обработчики (complete / ioerror), я меняю значение на error / complete, ожидая, что условие цикла while завершится ошибкой за доли секунды, но, похоже, этого не произойдет. Может быть ограничение самой flash / flex. (продолжение …)

3. Позвольте мне дать вам обзор того, чего я пытаюсь достичь. Это приложение по сути представляет собой игру (похожую на cityville), здесь у меня есть меню, чтобы показать все предметы, которые игрок может купить. В данный момент игрок выбирает элемент (шаг 1) по своему желанию, меню закрывается (шаг 2), а изображение выбранного элемента (скажем, дом, дерево) перемещается вместе с мышью (шаг 3), и в тот момент, когда игрок падает (шаг 4, щелчок по области воспроизведения), онодобавлено в этап (шаг 5).

4. Я пытаюсь динамически загрузить изображение между шагами 1 и 2, используя приведенный ниже код var img:SpriteImage = new SpriteImage(например,ImageUrl); img.prepare(); // просто ожидает загрузки изображения, но зависает var obj:DisplayObject = img; и событие перемещения мыши следует немедленно(шаг 3), теперь, как я могу остановить событие мыши? есть ли какой-нибудь способ остановить действия пользователя? как?

5. Извините за эти сбои. Я убиваю «plugin-container.exe » процесс, позволяющий избежать сбоев браузера / приложения flash builder

Ответ №2:

A ProgressBar может оживить ваш пользовательский интерфейс таким образом, чтобы он не зависал при загрузке изображения.

Посмотрите на документы Adobe для элемента управления ProgressBar. В параграфе, озаглавленном Создание элемента управления ProgressBar, приведен пример, который показывает, как отображать ProgressBar во время загрузки изображения.