Mastering the Tao of Personal Computing

my del.icio.us: ArticleS.UncleBob.TheThreeRulesOfTdd: Every programmer needs to bookmark this one http://bit.ly/6jONm 1 day ago

Flex Application Bootstrapping - Totally Custom Preloader

Jul 6th 2008
45 Comments
respond
trackback

I’m not going to define and discuss what a RIA is, but I rather stress here on one very important aspect of rich internet applications and in particularly saving time. Time is money (or opportunities for pleasures and entertainment), having more time is having more money (or opportunities for pleasures and entertainment), so that’s where ‘rich’ comes from. Flex applications that take eternity to load and don’t offer you something enough valuable as compensation for your patience are waiting in vain, just as in the song. This is one reason why rich internet applications come with very specific requirements and tight restrictions about what’s loaded and when. Chunks of functionality and data are dispersed in time and are ordered by their purpose in the concrete application.

The Specific Requirements

BombaySapphire.com - that’s a typical example. The requirements for the application loading can be summarized in the following diagram, where the gray bars depict the life-span of the different visual phases of the Bombay application, and the red ones are showing the time needed for loading the various parts and data, comprising the application. In case you wonder the LDA abbreviation stands for Legal Drinking Age validator.
Schematic Application Timeline
Instead of having all the gray bars be part of a monolithic whole, the guys from Adobe had provided us with the 2-frame Flex application model, where the first frame of the application is solely devoted on the preloader, while the second is available for the actual application.
Flex Application Two Frames Model
In the rest of the article I’m going to describe how to setup not just a skinned preloader, but a totally custom preloader. For those interested in just skinning the default Flex preloader - mx.preloaders.DownloadProgressBar - you should continue with Jesse Warden’s great article on the topic. But before proceeding with the implementation of the IPreloaderDisplay interface, we need to take a look at the Flex SystemManager and its responsibilities and also to get familiar with some events that the Preloader dispatches.

The Flex SystemManager

1. The SystemManager is the first display class created within a Flex application.
2. It is responsible for creating the Preloader and handling its events.
3. The SystemManager is also responsible for advancing the Flex application to the second frame once the application SWF is fully downloaded.

Besides these responsibilities directly related to the Preloader, the SystemManager is also responsible for:
4. Managing an application window and sending events if the size of the window changes.
5. Maintain tooltips, cursors and popup windows.
6. Expressly trapping the keyboard and mouse activity.
7. Some other stuff, I hadn’t time to read about.

Preloader’s most important events

1. ProgressEvent.PROGRESS
This is a typical progress event - it indicates what part of the application is loaded.
2. FlexEvent.INIT_PROGRESS
This event is dispatched when the Flex application completes an initialization phase - once the application SWF is fully loaded, the SystemManager advances the playhead to the next frame. Usually you’ll need to control the specific moment when the application advances to the second frame in the 2-frame model. In the samples below I’ll show one ways to achieve this - basically you need to capture the event, store it as pending and suspend the succeeding dispatches of these type of events - later you should re-dispatch the stored pending event.
3. FlexEvent.INIT_COMPLETE
This is the last event the Preloader dispatches. Next the Preloader should dispatch Event.COMPLETE indicating that the SystemManager is ready to remove the Preloader and to add the application to the display list.

Implementing the IPreloaderDisplay interface

I think this is the right place in the article to show you a sample implementation of the IPreloaderDisplay interface. Let’s start with the trivial part of the interface - some background and stage related properties. In the IPreloaderDisplay these are defined as get and set functions, which allows me to implement them by just declaring the corresponding public variables and annotating them with [Bindable], so the the compiler will generate the needed get and set-functions.

[Bindable] public var backgroundAlpha : Number;
[Bindable] public var backgroundColor : uint;
[Bindable] public var backgroundImage : Object;
[Bindable] public var backgroundSize : String;
[Bindable] public var stageHeight : Number;
[Bindable] public var stageWidth : Number;

The most convenient place for adding listeners for the events dispatched by the Preloader-component is in the set preloader() method of the interface.

private var _preloader : Sprite;
public function set preloader(value : Sprite) : void
{
    _preloader = value;

    _preloader.addEventListener(ProgressEvent.PROGRESS, onPreloaderProgress);
    _preloader.addEventListener(FlexEvent.INIT_PROGRESS, onPreloaderInitProgress,
        false, int.MAX_VALUE);
    _preloader.addEventListener(FlexEvent.INIT_COMPLETE, onPreloaderComplete);
}

The last method we must implement is the initialize() method. This method is called right after the Preloader is added as a child. This is the entry point where you can configure your preloader. For example I use this method to draw the background, filling it with a custom pattern or just adding visual components as children to this totally custom preloader.

public function initialize() : void
{
    // e.g. draw a background
    ...
    // or add visual children to the totally custom preloader
    ...
}

Let’s take a look how I handle the above mentioned event FlexEvent.INIT_PROGRESS:

private var readyToAdvanceToSecondFrame : Boolean = false;
private var pendingInitProgressEvent : FlexEvent;
public function onPreloaderInitProgress(e : FlexEvent) : void
{
    if (readyToAdvanceToSecondFrame)
    {
        pendingInitProgressEvent = e.clone();
        e.stopImmediatePropagation();
    }
}

It worths taking note on the way I’m subscribing to FlexEvent.INIT_PROGRESS:

_preloader.addEventListener(FlexEvent.INIT_PROGRESS, onPreloaderInitProgress,
    false, int.MAX_VALUE);

I’m setting the priority of the specified handler to the maximum possible value, making this handler the first one to execute when the event is dispatched.

Duplicating Binary Class Definitions

This probably needs a separate post, but I’ll share it here anyway. It is very possible that you’ll end up using a Flash component as your Preloader. The reasons for such a solution are clear. If your Preloader does a lot of stuff before your main application is even loaded, this better be a separate component. If you choose to put it in the application it will first increase the size of it, and second you’ll need to wait loading the whole application before using it. But making it separate imposes the question whether to use Flash or Flex when implementing it. Making this component a separate Flex application means you’ll have a preloader for the actual preloader, which is acceptable if you find a way how to load and use one Flex application inside of another Flex application. If you’ve done this, please share it with us and write a comment about it. Another thing we can’t rely on is whether the Flex framework is loaded - the size of the framework can be much bigger than the size of the Preloader you want to use.

Well, let’s assume we end up using a Preloader component written in Flash. When I did this I ran into a very subtle problem - duplicating binary class definitions. The picture below illustrates the problem:
Flex Application Domains
The Bombay Application Domain is the domain with the code of the main application. If this code holds a reference to the concrete type of the Flash-component, represented here by the LDA Application Domain we’ll run into trouble if the above application domain contains definitions of same classes - in this example the problematic duplication is the Tweener class. Such a duplication makes the application behave strange and unpredictable.

One way to avoid ugly situations like these is to use the exclude command before compiling the Preloader Flash component. The Flash 8 IDE provided this feature, but unfortunately it was removed from the new Flash IDE that has no such exclude definitions command.

Another way to avoid duplication is to avoid the above application domain to reference the concrete type of the Flash component. All you need to do is to encapsulate the preloader component under an interface Facade, thus the Flash component will conform with the Facade interface and the above application domain will not need to know the concrete type of the Flash component.

A Skeleton Implementation

I want to finish with a skeleton implementation, so you can base your code on it.

IPreloaderContentFacade.as:

package preloader
{
import flash.events.IEventDispatcher;

public interface IPreloaderContentFacade extends IEventDispatcher
{
    function setApplicationProgress(bytesLoaded : Number, bytesTotal : Number) : void;
}
}

TotallyCustomPreloader.as:

package preloader
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;

import mx.events.FlexEvent;
import mx.preloaders.IPreloaderDisplay;

public class TotallyCustomPreloader extends MovieClip implements IPreloaderDisplay
{
    public static const PRELOADER_CONTENT_URL : String = "preloader_content.swf";

    public var backgroundAlpha : Number;
    public var backgroundColor : uint;
    public var backgroundImage : Object;
    public var backgroundSize : String;
    public var stageHeight : Number;
    public var stageWidth : Number;

    private var _preloader : Sprite;
    public function set preloader(value : Sprite) : void
    {
        _preloader = value;

        _preloader.addEventListener(ProgressEvent.PROGRESS, onPreloaderProgress);
        _preloader.addEventListener(FlexEvent.INIT_PROGRESS, onPreloaderInitProgress,
            false, int.MAX_VALUE);
        _preloader.addEventListener(FlexEvent.INIT_COMPLETE, onPreloaderComplete);
    }

    private var preloaderContentFacade : IPreloaderContentFacade;

    public function TotallyCustomPreloader()
    {
        super();
        loadPreloaderContent();
    }

    public function initialize() : void
    {
    }

    private var loader : Loader;
    private function loadPreloaderContent() : void
    {
        loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderComplete);

	var loaderContext : LoaderContext = new LoaderContext(false, new ApplicationDomain());
	var request : URLRequest = new URLRequest(PRELOADER_CONTENT_URL);
	loader.load(request, loaderContext);
    }

    private function onLoaderComplete(e : Event) : void
    {
        preloaderContentFacade = IPreloaderContentFacade(loader.content);
        addChild(MovieClip(preloaderContentFacade));
    }

    private function onPreloaderProgress(e : ProgressEvent) : void
    {
        if (preloaderContentFacade != null)
        {
            preloaderContentFacade.setApplicationProgress(e.bytesLoaded, e.bytesTotal);
        }
    }

    private var readyToAdvanceToSecondFrame : Boolean = false;
    private var pendingInitProgressEvent : FlexEvent;
    private function onPreloaderInitProgress(e : FlexEvent) : void
    {
        if (!readyToAdvanceToSecondFrame)
        {
            pendingInitProgressEvent = e.clone();
            e.stopImmediatePropagation();
        }
    }

    private function onPreloaderComplete(e : FlexEvent) : void
    {
        readyToAdvanceToSecondFrame = true;
        if (pendingInitProgressEvent != null)
        {
            dispatchEvent(pendingInitProgressEvent);
        }
        dispatchEvent(new Event(Event.COMPLETE));
    }
}
}

This skeleton implementation is omitting a lot of things a real implementation can have - all depends on the specific requirements of the application you develop. But I think the code above is general enough to serve as a guideline for a concrete implementation.


This post is tagged , , , ,

45 Comments

  1. Nice explanation of how preloader works. I am using something similar to your custom preloader. However, i really like your skeleton implementation code. Are you planning to license that?

    I have a question, though. How can i create a popup that appears the moment SystemManager switches to the Flex application (Frame 2)? When i put my popup creation code in the creationComplete event, it pops up during the preloader.

  2. admin

    Hi, Kenneth,

    The information in my blog is covered by Creative Commons (check the footer for more details), but Creative Commons is not meant for licensing code, so feel free to use the skeleton code I’ve provided in this article under the MIT license. Grouping the code with this comment has actually the power of signing the code with the license of my choice:

    Copyright (c) 2008 Vladimir Tsvetkov
    
    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or sell
    copies of the Software, and to permit persons to whom the
    Software is furnished to do so, subject to the following
    conditions:
    
    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.
    
    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
    OTHER DEALINGS IN THE SOFTWARE.
    

    Now, to the questions:
    If I’m getting you right it seems to me you’re trying to do the following:

    dispatchEvent(new Event(Event.COMPLETE));
    PopUpManager.createPopUp( ... );
    

    If you’re doing this the popup will appear before the Preloader has been removed from the display. The Event.COMPLETE will cause the SystemManager to execute preloader_preloaderDoneHandler(), which will remove the Preloader and then will add the Application to the display. But creating your popup is such a manner is too early. You can try opening this popup on Application addedToStage - something like that:

    <mx:Application addedToStage="PopUpManager.createPopUp( ... );" ...
    

    Cheers

  3. Wow.. your suggestion “addedToStage” helped! i was looking for something instead of “show” or “creationComplete”.

    Regarding your code license, i noticed your Creative Commons logo on your blog. I’ll keep in mind your license.

    Thanks a lot!

  4. fabouney

    Great stuff, thanks a lot.
    Can you explain me the role of pendingInitProgressEvent.
    In my application I must load external sounds, and suspend the preloader until the sounds are completely loaded, in fact, I try to add a phase between the download and initialization.
    Or if not possible, after initialization.

  5. admin

    Good question! This certainly needs further explanation. This explanation involves some source code exploration of the Flex Framework. Take a careful look at the following method inside the mx.managers.SystemManager:

    /**
     *  @private
     *  Once the swf has been fully downloaded,
     *  advance the playhead to the next frame.
     *  This will cause the framescript to run, which runs frameEndHandler().
     */
    private function preloader_initProgressHandler(event:Event):void
    {
        // Advance the next frame
        preloader.removeEventListener(FlexEvent.INIT_PROGRESS,
                                      preloader_initProgressHandler);
    
        deferredNextFrame();
    }
    

    What happens in the fragment above is that the SystemManager advances the application to the next frame as soon as it gets the FlexEvent.INIT_PROGRESS event from the preloader.

    In order to suppress this advance to the next frame, we need to make the following things inside our custom preloader:
    1. Capture the FlexEvent.INIT_PROGRESS event before the SystemManager. You can achieve this by adding an event listener with the highest possible priority:

    preloader.addEventListener(FlexEvent.INIT_PROGRESS, onPreloaderInitProgress,
                false, int.MAX_VALUE);
    

    2. After you catch the event, you need to stop this event from further propagation, so the SystemManager won’t catch it. Think of the events as balloons full with gas, and think of your application as of a multi-storey building - event listeners with higher priority are on the lower floors, while the SystemManager is on top floor. Right now our custom preloader is on one of the first floors. It catches the event, and ties it with a rope to its balcony, so the balloon won’t ascend to the higher floors.

    if (!readyToAdvanceToSecondFrame)
    {
        pendingInitProgressEvent = e.clone();
        e.stopImmediatePropagation();
    }
    

    3. When you’re ready to advance to the second frame (e.g. your sound files are fully loaded), you need to re-dispatch the pendingInitProgressEvent. Untie the rope and let the balloon ascend to the top floor.

    if (pendingInitProgressEvent != null)
    {
        dispatchEvent(pendingInitProgressEvent);
    }
    

    I hope I’ve been of help to you!

  6. Devin

    Great explanation… I wonder though, if you could tell me why my preloader shows up so late and like half way through it’s progress. my Application is around 400k and it tends to confuse people when the preloader doesn’t show up for a few seconds… the page just looks empty.

    Thank you.

  7. admin

    Devin,
    It sounds pretty strange to me that your application has no activity at all for a few seconds.

    Any non-Flash dependencies of the SystemManager have to load in frame 1, before the preloader, or anything else, can be displayed. This can take some time, but I doubt it takes few seconds even if you use the default preloader - such a delay is possible on a very slow connection.

    One thing you can try is to use the Flash Player persistence caching of the Flex Framework. In the project properties you can choose to use the Flex Framework not as Merge into Code, but as a Runtime Shared Library, so the Flex Framework won’t be included in the size of SWF of your application. Further more the persistent cache will start storing the Flex Framework, so every subsequent loading of the application will be considerably faster.

    Check this out for more information on Flex Framework persistent caching.

  8. Bryan Dunbar

    Great article. But I have a question. I’ll explain my situation and maybe you can help me. I have an HTTPService that I want to call during the preload, before the application has been added to the stage. I’m trying to use your implementation to do this. What I’ve done is in the onDownloadComplete handler I’m calling my HTTPService. In trying to follow your code it seems like I would want to set readyToAdvanceToSecondFrame to true in the result event handler of the httpservice and dispatch the pendingInitProgressEvent at this point. However, after I dispatch that event its not getting back into my InitProgress event handler to allow flex to finish the init progress and effectively dispatch the complete event.

    Am I missing something? Do you have a working example using your skeleton code that may be helpful?

    Thanks!
    Bryan

  9. admin

    mx.rpc.http.HTTPService is part of the Flex framework, so keep this in mind when using it. This class wouldn’t be available until the Flex framework is fully downloaded. So you have two options:

    1. To call your web-service inside the preloader use something like this:

    private function onPreloaderComplete(e : FlexEvent) : void
    {
        // here should be safe enough to use Flex framework functionality as HTTPService
        // call your web-service here
    }
    
    private function onServiceResult(e : ResultEvent) : void
    {
        if (pendingInitProgressEvent != null)
        {
            dispatchEvent(pendingInitProgressEvent);
        }
        dispatchEvent(new Event(Event.COMPLETE));
    }
    

    In this scenario you don’t need the readyToAdvanceToSecondFrame flag, because you know for sure when your preloader is ready to advance to the next frame.

    2. Leave your preloader to do only pre-loading stuff - when it’s done, advance to the main application, but make the screen of the main application be exactly as the preloader, so you can continue smoothly with the application pre-loading logic and the user won’t even notice that he’s already in the main application.

    Sorry, but I can’t share the code of the real world example - but it uses this same skeleton.

  10. Phil

    Great article !

    How would you communicate to the main application the completed event from the pre-loader since it is encapsulated ? This is the case in which the pre-loader is in a different folder from your application… hence the duplicating classes right ? Please guide my understanding, so I catch the event , load the pre-loader and re-dispatch it.
    So say the pre-loader is loaded and then one wants to advance to the second frame for example by the click of a button… how would the re-dispatch work with in the pre-loader flash file while still keeping the movie encapsulated ?

    Thanks for the awesome article !
    Phil

  11. admin

    Hi, Phil,

    Thanks for your comment! I believe there is some confusion. Being in a separate Application Domain does not prevent events from propagating. Every component in the display list no matter the application domain it is placed in can dispatch events, and these events will propagate as expected.

    Nevertheless, when using different Application Domains you need to be very careful, because application domains are like containers for class definitions and loading third-party content can affect the class lookup within your application domain.

    Please, read this simple and clear explanation of Application Domains.

    I hope, I’ve understood your question correctly!

  12. Daniel

    Really good article, thank you!

    One thing I was hoping you could explain further though, was why you would want to create the IPreloaderContentFacade interface when the ‘preloader_content.swf’ is being loaded into a new Application domain. Wouldn’t that stop any duplication of binary class definitions?

    Thanks again!

    Dan

  13. I believe the default situation is loading into a child domain. Check this simple explanation of the Application Domains in Flex and see if my thoughts are in consistence with it.

    Probably loading the preloader code into a sibling domain will fix the issues of duplication or unwanted override of binary class definitions.

    The actual issue is unwanted override of binary class definitions.

    With the Facade interface we make sure the code of the preloader won’t depend on the code of the application - if it doesn’t depend on it, it won’t be needed to be linked by the compiler in the SWF.

    Another way to fix this issue is my using some sort of exclude directives for the Flash compiler. When we build this app, we hadn’t the time to write an exclude script for the new version of the Flash CS (the version back then was 3), so we stick to decoupling through interfaces.

    Thanks for the question Dan! Hope I gave you at least some direction where to seek for full clarity, because I’m ain’t sure I gave you a definitive answer. Right now I’m trying to answer by memory.

  14. for some reason the

    dispatchEvent(pendingInitProgressEvent);

    does not work for me. What im trying to do is stop initialization process via using the stopImmediatePropagation compared to the normal one. when i dont stop the event, the function onPreloaderInitProgress gets called as much as how many components are on the stage that needs to be initialized. At least that my theory from tracing the debug stops.
    So when I loaded the resource bundle resourceManager.loadResourceModule(..) and the function completes it goes back to the complete handler and dispatches the pending Event. But for some reason the normal action just does not resume and it just stops on that complete handler for loading the resource bundle.

    any ideas what im dong wrong?

    thanks.

  15. admin

    Hey, Tom!

    Which version of the SDK you’re using? I’ve received some indication that my skeleton code might be not working in latest versions of the Flex SDK, like 3.3 and 3.4. Flex 4 is probably totally different.

    Are you trying to load the resource module during the pre-loading?

  16. Hi thanks for the reply!

    Im using Flex v3.0 (build 3.0.2.214193)

    no. i actually waited for the preloader (swf made from flash) to complete so i could use it for the progress status. Anyway here is the complete sequence, where each item i wait to completly load before i fire the next one:

    - load the preloader loadPreloaderContent (swf file)
    - load the application
    - calls the onPreloaderInitProgress
    - from this point i stop event propagation (which works)
    - load the locale (swf file)
    - locale loading completes then dispatch the event dispatchEvent(pendingInitProgressEvent)

    from that point it does not continue to do anything it seems that nothign is listening to the event that was dispatched.

    so in effect out of curiosity i also fired an

    dispatchEvent(new Event(Event.COMPLETE));

    this will create a runtime error since the children of the app is not yet initialized.

    Let me know what your thoughts are. thanks in advance.

  17. oh sorry i looked at the sdk version on the compiler.. it says Flex sdk 3.2
    the one i gave you earlier is flex version itself.

  18. admin

    This looks like a tough issue to handle. Your sequence seems just fine.

    You can try debug the Flex SystemManager - search in it for event listeners for the FlexEvent.INIT_PROGRESS, put some breakpoints and take a glimpse what’s happening under the hood.

    Let me know if you have any progress on this issue!

  19. oh just an update.. i already solved it..
    it was too obvious actually i just read pass the mistake.
    as i stated earlier there seems nothing listens to the dispatched cloned event and its true!

    So the solution was to dispatch it via the preloader since in the first place that is where we subscribed our listener. The ending code should be like this.

    _preloader.dispatchEvent(pendingInitProgressEvent);

    instead of

    dispatchEvent(pendingInitProgressEvent);

    thanks for the reply anyways :)

  20. admin

    Great! I’m glad you’ve cracked it!

    Thanks for the interest in my articles!

  21. thanka as well for putting it out there.. it was helpful!

  22. flexit

    Hello, very nice article. Since this seem to be related to the preloader topic, I was just wondering if you ever seen this exception:

    Error: Error #1000: The system is out of memory.

    at global$init()
    at flash.display::MovieClip/nextFrame()
    at mx.managers::SystemManager/deferredNextFrame()
    at mx.managers::SystemManager/preloader_initProgressHandler()
    at flash.events::EventDispatcher/dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at mx.preloaders::Preloader/timerHandler()
    at flash.utils::Timer/_timerDispatch()
    at flash.utils::Timer/tick()

    If you could shine some light on this issue it would be greatly appreciated, since I pretty much stuck on what may cause this and/or how to go around it. btw. this happens in both Flash Player 9 and 10.

    Thanks in advance.

  23. admin

    Hi, first of all, thanks for stopping by.

    The moment you see the word “memory” in the error message, this should signal you that you need to run your application through the Flex Profiler. Place a brake-point at the first line of the SystemManager.preloader_initProgressHandler(), stop the application there and check what eats so much memory.

    Let me know if you have any progress on this issue!

  24. flexit

    Oh, we have ran it thru the profiler many, many times. I will try your suggestion anyway, since we’ve never stopped it that line and looked at the memory footprint. I’ll report back once I run the experiment. Meanwhile, the memory may be, but definitely not the only issue. You see, our app takes about 45-65 mb, not too small, but not extremely big by RIA standards (I suppose). The problem arrises when we want to run several instances of the app. We can generally run somewhere 8-10 instances of it before the exception is thrown. Note that the total memory usage by flash is usually between 500 and 600 mb at that point, while the browser (be it IE6,7, Firefox, or Chrome) are at about 800 mb mark. I’ve also been able to outright crash the browser just by launching like 50+ instances of a very simple small (6mb) app. In the (50+ small app) experiment the browser memory usage was also at around 800 mb when it crashed. So, you are definitely correct in asserting that ‘memory’ plays a role, but it is not clear what/why? Another experiment I’ve tried was to just run up the memory usage by running one simple app which kept allocating bunch of strings. In this experiment the browser crashed only when its memory usage reached 1.6mb which is expected given WinXP 32bit OS limitation.
    Again, thank you very much for taking the time to answer my post. I really do appreciate it.

  25. flexit

    I am also not sure how to get the app to stop at a breakpoint while running the profiler. Simply, setting a break point and running the profiler doesn’t seem to break on the breakpoint. If you could clarify how to accomplish that, please. Thank you.

  26. admin

    You’re totally right. There is no way to put a break-point inside the profiler, but you can choose to do these couple of approaches:
    1. Run your application in Debug mode, but before that try using in the code the flash.sampler.* API (This is the API that the Flex Profiling agent is using).
    2. Run your application in Profiler mode, but try to handle the INIT_PROGRESS event before the SystemManager handles it. Inside this event handler you can try to pause the profiler again with the help of the flash.sampler.* API (check the reference documentation of flash.sampler.pauseSampling()).

    Disclaimer: I haven’t tried these two approaches and I’m not an authority in how you should use the flash.sampler API. This is just some ideas and probably I would try both of them if I was dealing with your issue.

  27. I’m getting an error saying that the class doesn’t use the function get backgroundAlpha()

    but when I add the function it throws the error duplicate function name get backgroundAlhpha()

    ?

    Can you help explain this?

  28. admin

    Sorry, about that! For the sake of brevity instead of writing get and set-functions I’ve wrote public variables (and I’ve forgot to annotate them with [Bindable]), but the IPreloaderDisplay has a get and set-function defined in it. Without the [Bindable]-tag the compiler won’t generate the get and set-functions.

    Use this:

    private var _backgroundAlpha : Number;
    public function get backgroundAlpha() : Number
    {
        return _backgroundAlpha;
    }
    public function set backgroundAlpha(value : Number) : void
    {
        _backgroundAlpha = value;
    }
    

    or try this:

    [Bindable] public var backgroundAlpha : Number;
    

    Please, let me know if that worked for you!

  29. Lorenzo

    Dear Vladimir, I really appreciate your blog! It’s very interesting!!

    I’d like to ask you a question. It’s not directly concerning your post but I would appreciate if you could help me.

    I’m trying to understand the Life Cycle used by Flex Application.

    I’ve done a little research on this argument; the two key concepts used into the FlashPlayer are:
    - SWF Frame: it’s the logical unit that contains graphical code and as code
    - Flash Player Frame: it’s the time interval used by Flash runtime to update the screen and defined by frameRate property

    Ok? If so, Could you explain me the relationship bewteen these two concepts? In particular, if they are paired togheter or not.

    Then, a Flex app has two SWF Frames: the first one contains contains the Preloader and the SystemManager; the second one the rest of the application. In this context how can you “link” SWF Flex Frame with Flash Player Frame?

    Thank you very much. Best regards.

  30. Hi Lorenzo,

    Thanks for the interest. First, I want to clarify the terminology you use, so the rest of the readers will understand you better:

    1. Flex applications are nothing else but applications running on the Flash platform, and as every Flash application, Flex applications also had to obey to the rules and the internals of the Flash player. Understanding how the Flash player works is really helpful and in some situation such understanding is essential.

    2. To understand how the Flash player works, you can check out my presentation from the Flex training program I’ve prepared - Overview of the Flex SDK. This overview covers the basics of the Flash internals, as well as the architecture of the Flash Player. From the slides there you’ll also learn that the Flash player executes an infinite loop of running through ActionScript code and rendering on the screen.

    3. To understand the relation between the Flash Player frame rate and the actual performance you get (usually lower than the preconfigured frame rate of our apps), you need to grasp the concept of the elastic racetrack. You should definitely read about the Flash Player Mental Model. Intuitively, the more code you have to execute on each frame, the slower the frame rate is.

    4. When you have a sound understanding about the Flash Player, let’s see how the Flex Framework apps are utilizing it! First the SWF is a streaming format - the player will start the application as soon as the player is loaded the first frame of the app. And while executing it, it continues loading the rest of the frames that comprise the app. Think of it as a movie clip in YouTube - you’re watching it, while it continues loading the rest of it. Same with all SWFs.

    If the Flex applications where comprised from a single frame, then the app would start when the whole app is loaded. For a big application this means the user sitting and watching a white screen for half a minute, which is unacceptable. Dividing it into 2 frames allows the initial loading of the first frame to be really fast (some fragments of the second), and to show a preloader which will indicate to the user that the application continues loading. The main part of the app is on the second frame.

    Flex applications are trying to abstract (hide) in a way what’s happening under the hood of the Flash player, but when you need to make such custom preloader you need to uncover all these details. So feel free to ask me any other questions.

    Hope, I’ll hear back from you!

  31. Lorenzo

    Dear Vladimir, thank you for your prompt reply.
    I’ve read your presentation. It’s absolutely fantastic!

    The only thing that it’s not clear for me is the relationship between them. In particular I would know what is a SWF Frame and how they are link with Flash Player Frame (or loop as you talked about) - understood as the time period between two consecutive enterFrame events.

    The main rule is: the Flash Player streams in a swf; until a full SWF Frame is read, the Flash Player cannot render it.

    I’ll try to explain what I need to understand and I hope my explanation will be clear.

    For the sake of simplicity, suppose you have a two frame application: SWF FR 1 and SWF FR 2.

    In general (for example in CS4) a frame is considered as a logical unit (delimited by ShowFrame tag) where you can attach as3 code. This as a simplified version of a swf file, i think:

    * Header // frameRate is defined here
    * Symbols, classes etc… // this is FR1
    === ShowFrame ===
    * Symbols, classes etc… // this is FR2
    === ShowFrame ===
    End

    If you have two frame, FR1 and FR2, Flash starts executing FR1 and goes to the next one (FR2). If you don’t stop the excution, the Player executes code contained into FR1 and FR2 through an infinite loop.

    On the contrary, when you stop the execution, for example in FR2, the flash player loops executing code contained in FR2.

    So, can Flash Player Frames took place many times per SWF Frame?

    When FR1 is downloading (FR1 is not fully loaded) is there any enterFrame events or not? Does the first frameEvent take place when the FR1 is fully loaded? During what period of time is FR1 rendered?

    An other scenario, if you have a stop into FR1, you will get enterFrame at the rate you specify (the current frame is FR1). Meanwhile FR2 is downloading. When it’s finished, you go to the next frame (FR2). During what period of time is FR2 rendered? Does Flash Player try to render FR2 to its next time interval?

    Take in account this sequence:

    1. FR1 is downloading
    2. FR1 is fully downloaded
    3. FR1 calls stop() method, meanwhile FR2 is downloading
    4. FR2 is fully downloaded
    5. Go to FR2
    6. FR2 calls stop() method

    Could you underscore for me when Flash Player enterFrame events take place?

    Finally, how does this model fit into Flex Applications?

    Thank you for your patience. Best regards.

  32. Shilpa

    Hi,
    I am trying to upload an image as a Preloader. This blog gives a fantastic idea of how one can add an image / swf file. But I am getting an exception saying that “Load never completed”.

    Can anyone help me with this exception.

  33. admin

    Looks like you’ve given a wrong URL, or at the location of the URL there is no image.

  34. Lorenzo

    Dear Valdimir, could you say to me if my second post reasoning is right or not. Thank you in advance. Best Regards. Lorenzo.

  35. Hi, Lorenzo,

    Sorry for getting back to you a week later, but you know how it is - it’s very easy to get sucked up in pursuit of deadlines.

    1. FR1 is downloading
    2. FR1 is fully downloaded
    3. FR1 calls stop() method, meanwhile FR2 is downloading. There is no explicit call to the stop() method - the Flash internals are hidden from us. Instead enterFrame is dispatched.
    3.1. Frame constructors are executed, frameConstructed is dispatched, and then the ActionScript code inside the frame gets executed.
    3.2. Exit frame is dispatched if FR2 is fully downloaded, else it sits there and waits.

    4. FR2 is fully downloaded….Go to FR2

    Does that answer your question?

  36. Lorenzo

    Thank you for your time Vladimir.

    Frame concept is a tricky topic and it’s difficult to understand. What could you say about my swf interpretation? Could you please explain me in more detail from 3 to 3.2? In particular, what do you mean by “Exit frame is dispatched if FR2 is fully downloaded, else it sits there and waits”? Does the FlashPlayer dispatch any other event?

    Thank you again. Best Regards. Lorenzo.

  37. Lorenzo, keep in mind that this is more of a mental model, rather than an exact technical description of how the Flash Player internals are working.

    To elaborate more on the frame life-cycle, you can check slide #18 from this presentation.

    What happens during one frame is slightly different than what I’ve described to you. The difference is in that the exitFrame event is dispatched directly before the frame rendering.
    If the next frame is still downloading then the playhead is not moving forward. As soon as the next frame is there, the playhead advances to the next frame.

  38. Lorenzo

    Thank you for your patience Vladimir! Could I ask you two more questions?

    The first one: Can I consider this sequence as a simplified version of a swf file created by Flex compiler?

    * Header // frameRate is defined here
    * Symbols, classes etc… // first SWF Frame: contains SystemManager Preloader
    === ShowFrame ===
    * Symbols, classes etc… // second SWF Frame: contains the Application
    === ShowFrame ===
    End

    The second one: The Flash Player streams in a swf; until a full SWF Frame is read, the Flash Player cannot render it. So, can Flash Player Frames take place many times per SWF Frame? If so, does the number of Flash Player Frame depend on SWF Frame size?

    Thank you very much.

    P.S. Sorry to be so insistent, but this argument is very interesting. I haven’t found any article on it. Do you know where I can find any background material?

  39. admin

    Yeah, Lorenzo. You’re on the right track!

    Each Flash cycle of executing ActionScript and rendering is considered a frame. So, you can have a MovieClip which timeline contains only 1 frame and this means that the playhead will stay forever on this single frame, but this doesn’t mean that the Flash player will stop looping through its cycle of executing ActionScript and rendering.

Leave a Reply