Here’s another help hint for those working with Modules in Flex: Watch your variable scope!!
When loading modules, you have a number of options for loading the SWF including the ModuleLoader and ModuleManager. If neither of those fit your needs you always have access to Flash’s Loader class. ModuleManger can be used for fine grained control of the loading process. Either way, variable scope plays a crucial roll in the loading process.
Here’s an example using ModuleLoader…
public function loadSWFModule(swfURL:String):void
var moduleLoader:ModuleLoader = new ModuleLoader();
moduleLoader.url = swfURL;
The moduleLoader is declared as a local variable. As it turns out this will cause problems, even with the ‘strong’ event listeners. For those not wanting to read the technical details to follow, simply use avoid using a locally scoped variable.
The following are some of the symptoms you may run into using the latter locally scoped variable:
To help those searching the net, I’ll be a bit redundant in the ‘symptom’ descriptions so hopefully you’ll find this post if you’ve stumbled upon this problem
The module fails to load the first time, but loads successfully the second time.
The ModuleEvent.READY is never dispatched
The ModuleInfoProxy never picks up the ModuleEvent.READY dispatched by ModuleInfo
ModuleInfo.clearLoader() throws an error (which is quietly caught), Error #2029: This URLStream object does not have a stream opened when calling loader.close()
The problem comes in when the Loader finishes loading the SWF. ModuleInfo’s internal listener list (listeners attached during ModuleInfoProxy’s constructor) are lost (i.e. null) when ModuleInfo finally reaches it’s readyHandler( ) method. At the end of the readyHandler( ), a ModuleEvent.READY event is dispatched.
With the listener list being null, the event is never picked up by the ModuleInfoProxy and the initial load fails.
On subsequent loads (i.e. the second time) ModuleInfoProxy’s load( ) method checks to see if the info has already been loaded and dispatches the ModuleEvent.READY event directly.
else if (info.loaded)
//trace("Module[", url, "] load is already loaded");
Causing the load to ‘work’ the second time.
My understanding is that Garbage Collection is often invoked when a module is loaded. It looks like it’s the cause of this behavior (the listeners being lost). I assumed that the ‘strong’ listeners would be enough to keep the GC away, oh well.
Again the solution is simple, make sure your not using a locally scoped variable when loading modules.