Forcing Flex to update the screen?

前端 未结 6 1732
梦谈多话
梦谈多话 2021-01-05 05:28

This may be a bit of a beginners question, but I can\'t for the life of me figure it out.

I\'m using flex to develop a GUI for a large project, specifically a status

相关标签:
6条回答
  • 2021-01-05 05:54

    Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.

    It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.

    The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:

    1. Progress initialized.
    2. Do some work.
    3. Update progress bar to 12. (invalidate display list)
    4. setTimeout(doMoreWork, 100);
    5. Update progress bar to 52.

    (if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).

    0 讨论(0)
  • 2021-01-05 06:03

    Glenn,

    That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).

    The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().

    Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:

    // Change this to a number that works... it will probably be over 1, depending on what you're doing.
    private const TOTAL_CALL_COUNT:int = 5;
    
    private var _timesCalled:int = 0;
    
    //----------------------------------------------------------------
    private function set Progress( progress:int ):void
    {
        progressBar.value = progress;
        DoNextFunction();
    }
    
    //----------------------------------------------------------------
    private function DoNextFunction():void
    {
        if( _timesCalled >= TOTAL_CALL_COUNT )
        {
            _timesCalled = 0;
            Function();
        }
        else
        {
            _timesCalled++;
            callLater( DoNextFunction );
        }
    }
    
    0 讨论(0)
  • 2021-01-05 06:04

    Sometimes its necessary set to zero before assign another value. progressBar.setProgress(0, progressBar.maximum); progressBar.setProgress(newValue, progressBar.maximum);

    0 讨论(0)
  • 2021-01-05 06:04

    I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.

    But I will try to find some new ways of doing it.

    The main purpose of my post is the complexity adobe has build around flash. When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.

    By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.

    0 讨论(0)
  • 2021-01-05 06:06

    Try calling invalidateDisplayList() after each changes to your progress bar. Something like :

    Class StatusBar
    {
    
        public function set progress(value:uint):void
        {
            progressBar.value = value;
            progressBar.invalidateDisplayList();
        }
    }
    

    Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.

    0 讨论(0)
  • 2021-01-05 06:11

    As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.

    If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.

    This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.

    0 讨论(0)
提交回复
热议问题