Pergunta

Em um aplicativo AIR Eu tenho o seguinte código:

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

No final de cpuIntensiveCalc o diálogo é removido. Os informa diálogo o usuário que "algo está acontecendo, esteja por favor perto."

O problema é que cpuIntensiveCalc começa antes do diálogo empates. Assim, a experiência do usuário é que os congelamentos de aplicação por 10 segundos com nenhum indicador, então o diálogo modal pisca rapidamente (menos de um segundo) na tela.

Os documentos Adobe dizer isso sobre creation_complete

Enviado quando o componente terminou sua construção, processamento de propriedade, medidas, layout e desenho.

Então, este se sente como o evento correto.
Em nome da completude, eu também tentou

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

Mas tinha os mesmos resultados.

TIA

Nenhuma solução correta

Outras dicas

A razão para isso é que o Flash Player é único segmento, e assim você está bloqueando a interface do usuário de reagir ao Popup diálogo até que o pedaço de matemática está terminado.

Hacky correção tempo ...

Você tem duas opções.

(Isto se deve trabalhar, mas não foi testado) Enrole a chamada cpuIntensiveCalc () em um callLater, de modo que a interface do usuário pode terminar tornando antes de bloquear a prestação.

ou

Use "Threads verdes" para quebrar o seu processamento para que você não bloquear completamente o processamento UI. Dê uma olhada .

(eu só tinha a mesma questão => mesmo que esta discussão é velha, eu só queria contribuir com a minha solução)

(disclaimer: este é um pouco feio, mas eles dizem que é ok na camada UI ... ;-))

Flex é de rosca única (pelo menos do ponto de vista do nosso desenvolvedor, acho que por trás das linhas de cena são utilizados pela VM)

=> você normalmente executar o seu código no segmento interface do usuário, depois que o usuário fez alguma ação em um widget. Qualquer chamada para atualizar um componente UI (como setProgress ou setLabel) só será processado na tela no final do ciclo de render (ver ciclo de vida novamente UIComponent).

=> Em therory chamando "cpuIntensiveCalc" em um callLater vai deixar a exibição quadro seu pop-up antes de executar o método.

Na prática, porém, eu notei que você normalmente tem que ter um par de cylces UI antes do pop-up ser exibido, como este:

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

MuchLaterRunner sendo definida assim:

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

    }

O problema é o mesmo ao chamar setProgress depois: é preciso dividir cpuIntensiveCalc em pequenos métodos que podem ser chamados que pode ser executado em cada ciclo de UI, caso contrário, a barra de progresso não será, err, progredir.

evento Use enterFrame em popup. Não se esqueça de remover o ouvinte no manipulador de eventos enterFrame - caso contrário, o método intensivo da CPU será chamado em cada quadro, batendo a sua aplicação. Se isso não funcionar, em primeiro lugar, usar um número privado como um contador e manter incrementá-lo no manipulador quadro entrar - chamada cpu método pesado somente quando o contador atingir o valor apropriado. Encontre o valor 'apropriado' por tentativa e erro.

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top