Pregunta

En una aplicación de AIR tengo el siguiente código:

  

theDialog = PopUpManager.createPopUp (esto, TheDialogClass, true) como TheDialogClass;   theDialog.addEventListener (FlexEvent.CREATION_COMPLETE, cpuIntensiveCalc);

Al final de cpuIntensiveCalc se elimina el cuadro de diálogo. El cuadro de diálogo informa al usuario de que " algo está sucediendo, por favor, espere. & Quot;

El problema es que cpuIntensiveCalc se inicia antes de que se dibuje el diálogo. Entonces, la experiencia del usuario es que la aplicación se congela durante 10 segundos sin un indicador, luego el diálogo modal parpadea rápidamente (menos de un segundo) en la pantalla.

Los documentos de Adobe dicen esto acerca de creation_complete

  

Se distribuye cuando el componente ha terminado su construcción,   Procesamiento de propiedades, medidas, layout y dibujo.

Así que esto se siente como el evento correcto.
En nombre de la integridad, también lo intenté

  

theDialog = PopUpManager.createPopUp (esto, TheDialogClass, true) como TheDialogClass;   cpuIntensiveCalc ();

Pero tuvo los mismos resultados.

TIA

No hay solución correcta

Otros consejos

El motivo de esto es que Flash Player es de un solo subproceso, por lo que está impidiendo que la IU reaccione a la ventana emergente de diálogo hasta que finalice el fragmento matemático.

Tiempo de reparación de Hacky ...

Tienes dos opciones.

(Este debería funcionar, pero no está probado) Envuelva la llamada cpuIntensiveCalc () en un CallLater, de modo que la IU pueda finalizar la representación antes de bloquear la representación.

O

Utilice " Hilos verdes " para dividir el procesamiento de modo que no bloquee completamente el procesamiento de la interfaz de usuario. Eche un vistazo .

(Solo tuve el mismo problema = > incluso si este hilo es antiguo, solo quería contribuir con mi solución)

(descargo de responsabilidad: esto es un poco feo, pero dicen que está bien en la capa de UI ... ;-))

Flex es un solo hilo (al menos desde la perspectiva de nuestro desarrollador, creo que los hilos ocultos son utilizados por la máquina virtual)

= > normalmente ejecutas tu código en el hilo de la interfaz de usuario, después de que el usuario realizó alguna acción en un widget. Cualquier llamada para actualizar un componente de la interfaz de usuario (como setProgress o setLabel) solo se procesará en la pantalla al final del ciclo de procesamiento (consulte nuevamente el ciclo de vida de UiComponent).

= > En la llamada a la llamada " cpuIntensiveCalc " en un callLater, el marco mostrará su ventana emergente antes de ejecutar el método.

Sin embargo, en la práctica, noté que normalmente tienes que tener un par de ciclos de UI antes de que se muestre la ventana emergente, como esto:

new MuchLaterRunner(popup, 7, cpuIntensiveCalc).runLater();

MuchLaterRunner se define de esta forma:

public class MuchLaterRunner
    {
        var uiComp:UIComponent;
        var currentCounter = 0;
        var cyclesToWaitBeforeExecution=0;

        var command:Function;

        public function MuchLaterRunner(uiComp:UIComponent, cyclesToWaitBeforeExecution:uint, command:Function)
        {
            this.uiComp = uiComp;
            this.command = command;
            this.cyclesToWaitBeforeExecution =cyclesToWaitBeforeExecution;
        }

        public function runLater() {

            currentCounter ++;
            if (currentCounter >= cyclesToWaitBeforeExecution) {
                uiComp.callLater(command);
            } else {
                // wait one more cycle...
                uiComp.callLater(runLater);
            }
        }

    }

El problema es el mismo cuando se llama a setProgress después: debemos dividir cpuIntensiveCalc en pequeños métodos que se pueden ejecutar en cada ciclo de UI, de lo contrario, la barra de progreso no se errará, no avanzará.

Usa el evento enterFrame en la ventana emergente. No olvide eliminar el agente de escucha en el controlador de eventos enterFrame; de ??lo contrario, se llamará al método intensivo de CPU en cada marco y se bloqueará su aplicación. Si esto no funciona al principio, use un número privado como contador y continúe incrementándolo en el controlador de marco de entrada: llame al método cpu heavy solo cuando el contador alcance el valor apropiado. Encuentre el valor 'apropiado' por camino y error.

theDialog = PopUpManager.createPopUp(this, TheDialogClass, true) as TheDialogClass;
theDialog.addEventListener(Event.ENTER_FRAME, onEnterFrame);
private function onEnterFrame(e:Event):void
{
  //can use theDialog instead of e.currentTarget here.
  (e.currentTarget).removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  cpuIntensiveCalc();
}
//in case the above method doesn't work, do it the following way:
theDialog.addEventListener(Event.ENTER_FRAME, onEnterFrame);
private var _frameCounter:Number = 0;
private function onEnterFrame(e:Event):void
{
  _frameCounter++;
  var desiredCount:Number = 1;//start with one - increment until it works.
  if(_frameCounter < desiredCount)
    return;
  //can use theDialog instead of e.currentTarget here.
  (e.currentTarget).removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  cpuIntensiveCalc();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top