سؤال

في تطبيق AIR لدي البرمجية التالية:

<اقتباس فقرة>   

وtheDialog = PopUpManager.createPopUp (هذا، TheDialogClass، صحيح) كما TheDialogClass.   theDialog.addEventListener (FlexEvent.CREATION_COMPLETE، cpuIntensiveCalc)؛

وفي نهاية cpuIntensiveCalc تتم إزالة الحوار. حوار بإعلام المستخدم بأن "شيئا ما يحدث، يرجى الوقوف إلى جانب".

والمشكلة هي أن cpuIntensiveCalc يبدأ قبل اقتراب الحوار. حتى تجربة المستخدم هو أن تطبيق يجمد لمدة 10 ثانية مع عدم وجود مؤشر، ثم ومضات حوار مشروط بسرعة (أقل من ثانية) على الشاشة.

وومستندات أدوبي يقول هذا عن creation_complete

<اقتباس فقرة>   

وارسلت عندما المكون قد انتهى بنائه،   معالجة الملكية، والقياس، والتخطيط، والرسم.

وحتى هذا يبدو وكأنه حالة الصحيح.
بسم اكتمال، كما أنني حاولت

<اقتباس فقرة>   

وtheDialog = PopUpManager.createPopUp (هذا، TheDialogClass، صحيح) كما TheDialogClass.   cpuIntensiveCalc ()؛

ولكن كان على نفس النتائج.

وTIA

لا يوجد حل صحيح

نصائح أخرى

والسبب في ذلك هو أن فلاش لاعب هو مترابطة واحد، وهكذا كنت منع UI من الرد على قافزة الحوار حتى يتم الانتهاء من قطعة الرياضيات.

ووقت الإصلاح Hacky ...

ولديك خياران.

و(هذا واحد يجب أن تعمل، ولكن لم تختبر) لف دعوة cpuIntensiveCalc () في callLater، بحيث يمكن للUI الانتهاء من تقديم قبل منع التقديم.

أو

استخدم "الأخضر المواضيع" لتفريق معالجة الخاص بك بحيث لا تحجب تماما تجهيز UI. نلقي نظرة .

و(لقد كان نفس القضية => حتى لو كان هذا هو الخيط القديم، أردت فقط أن تساهم حل بي)

و(تنويه: هذا هو قبيح قليلا، لكنهم يقولون أن على مايرام في طبقة UI ... ؛-))

وفليكس غير مترابطة واحد (على الأقل من وجهة نظرنا المطور، وأعتقد أن وراء المواضيع المشهد يتم استخدامها من قبل VM)

و=> يمكنك عادة تنفيذ التعليمات البرمجية في موضوع UI، بعد فعل المستخدم بعض الإجراءات على القطعة. لن يتم تقديمها أي دعوة لتحديث عنصر واجهة المستخدم (مثل setProgress أو setLabel) على الشاشة في نهاية دورة تقديم (انظر دورة الحياة مرة أخرى UiComponent).

و=> في therory الدعوة "cpuIntensiveCalc" في callLater سيتيح إطار عرض المنبثقة قبل تنفيذ الأسلوب.

في الممارسة على الرغم من أنني لاحظت أن يكون لديك عادة أن يكون لبضعة cylces UI قبل يتم عرض المنبثقة، ومثل هذا:

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

وMuchLaterRunner يجري تحديد مثل هذا:

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

    }

وهذه القضية هي نفسها عند الاتصال setProgress بعد ذلك: يجب علينا أن تقسيم cpuIntensiveCalc إلى طرق للاستدعاء الصغيرة التي يمكن أن ركض في كل دورة UI، وإلا فإن progressbar لن، يخطئ، والتقدم.

والحدث استخدام enterFrame على المنبثقة. لا ننسى أن إزالة المستمع في معالج الأحداث enterFrame - وإلا سيتم استدعاء الأسلوب المكثف وحدة المعالجة المركزية في كل إطار، تحطمها التطبيق الخاص بك. إذا لم تنجح هذه الطريقة في البداية، واستخدام عدد الخاص وعداد والحفاظ على تزايد في معالج إطار إدخال - استدعاء وحدة المعالجة المركزية طريقة الثقيلة فقط عندما تصل العداد القيمة المناسبة. العثور على قيمة "المناسبة" التي درب والخطأ.

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();
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top