Frage

In einer AIR-Anwendung, die ich den folgenden Code haben:

  

theDialog = PopUpManager.createPopUp (this, TheDialogClass, true) als TheDialogClass;   theDialog.addEventListener (FlexEvent.CREATION_COMPLETE, cpuIntensiveCalc);

Am Ende des cpuIntensiveCalc wird der Dialog entfernt. Der Dialog informiert den Benutzer, dass „etwas los ist, bitte per stehen.“

Das Problem ist, dass cpuIntensiveCalc beginnt, bevor der Dialog zieht. So dass der Benutzer Erfahrung ist, dass die Anwendung friert für 10 Sekunden ohne Indikatoren, dann wird die modale Dialog blinkt schnell (weniger als eine Sekunde) auf dem Bildschirm.

Die Adobe docs sagen, dass dies über creation_complete

  

Wird ausgelöst, wenn die Komponente den Bau abgeschlossen,   Eigentum Verarbeitung, Mess-, Layout und Zeichnung.

Also das fühlt sich an wie das richtige Ereignis.
Im Namen der Vollständigkeit, ich habe auch versucht,

  

theDialog = PopUpManager.createPopUp (this, TheDialogClass, true) als TheDialogClass;   cpuIntensiveCalc ();

Aber hatte die gleichen Ergebnisse.

TIA

Keine korrekte Lösung

Andere Tipps

Der Grund dafür ist, dass der Flash Player Single-Threaded ist, und so blockieren Sie die Benutzeroberfläche von zum Dialog Popup reagieren, bis die Mathematik chunk beendet ist.

Hacky fix Zeit ...

Sie haben zwei Möglichkeiten.

(Dies sollte funktionieren, ist aber nicht getestet) Wickeln Sie das cpuIntensiveCalc () -Aufruf in einem calllater, so dass die UI-Rendering beenden können, bevor Sie die Wiedergabe sperren.

oder

Mit „Green Threads“ Ihre Verarbeitung zu brechen, so dass Sie nicht vollständig die UI Verarbeitung blockieren können. Werfen Sie einen Blick .

(Ich hatte gerade das gleiche Problem => auch wenn dieser Thread ist alt, ich wollte nur meine Lösung beizutragen)

(Disclaimer: Dies ist ein bisschen hässlich, aber sie sagen, das ist in Ordnung in der UI-Ebene ... ;-))

Flex ist Single-Threaded (zumindest aus Sicht unserer Entwickler, ich glaube, hinter den Kulissen Fäden werden von der VM verwendet)

=> Sie in der Regel Ihren Code in dem UI-Thread ausgeführt werden, nachdem der Benutzer eine Aktion auf einem Widget tat. Jeder Aufruf eine UI-Komponente zu aktualisieren (wie setProgress oder setLabel) wird erst am Ende des Zyklus machen (siehe wieder UIComponent Lebenszyklus) auf dem Bildschirm dargestellt werden.

=> In therory calling "cpuIntensiveCalc" in einem calllater wird der Rahmen angezeigt werden Ihr Popup lassen, bevor die Methode ausgeführt wird.

In der Praxis aber ich bemerkte, Sie in der Regel für ein paar UI Takte haben, bevor die Popup-Fenster angezeigt werden, wie folgt:

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

MuchLaterRunner wie folgt definiert ist:

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

    }

Das Problem ist das gleiche, wenn setProgress Aufruf danach: wir cpuIntensiveCalc in kleine aufrufbare Methoden teilen müssen, die an jedem UI-Zyklus laufen werden können, da sonst die progressbar wird nicht, äh, Fortschritt.

Verwenden enterframe-Ereignis auf Popup. Vergessen Sie nicht, den Hörer in den enterframe-Ereignishandler zu entfernen - sonst wird die CPU-intensive Methode wird in jedem Frame aufgerufen wird, stürzt die App. Ist dies nicht auf den ersten nicht funktioniert, eine private Nummer als Zähler verwendet werden und halten es in der Frame-Handler eingeben Erhöhen - nur cpu schwere Methode aufrufen, wenn der Zähler den entsprechenden Wert erreicht hat. Finden Sie den ‚angemessen‘ Wert durch Pfad und Fehler.

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();
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top