After struggling with a really annoying problem debugging in FB3, I finally managed to get my dynamically loaded modules to work properly!
Environment:
Win XP
Flex Builder 3.0.2.214193
Flex SDK 3.5.0.12683
Air 2.5
We're currently developing a large standalone application with multiple tab-driven screens. We have a collection of tabs each of which load a different instance of a module - defined by a configuration file - loaded dynamically at runtime.
Although this works perfectly when run outside of FB, when run in debug, 70% of the time the modules fail to fire the READY event. This is extremely annoying if you're trying to debug something within the modules.
I found a couple of bugs in Adobe's JIRA system that seemed to be ralted, these were for browser based AIR apps but seemed too close to ignore.
After a bit of headscratching, I reread this line in the docs
"Be sure to define the module instance outside of a function, so that it is not in the function's local scope. Otherwise, the object might be garbage collected and the associated event listeners might never be invoked."
This got me thinking, so I rechecked the code and realised that although the declaration of the module variable was outside the function, the definition was inside of a loop so the above might still apply. So I added each ModuleInfo instance to an ArrayCollection and moved the 'load' call to a second loop which runs after the loop that sets up the instances and attaches the event handlers. This seems to have done the trick.
Conclusion:
If you dynamically load modules in a loop, you are in danger of running into the 'non-sequential' loading problem that the above bugs relate to, so do the module loading in a separate loop after finishing instantiating all the modules.
Example Psuedocode Implementation
//instantiate the modules you need
for each (moduleDef) {
moduleInfo = ModuleManager.getModule('module.swf');
moduleInfo.addEventListener(ModuleEvent.READY, moduleReady);
//add new module to array collection
moduleInfos.addItem(moduleInfo);
}
//call each module's load method
for each (var mi: IModuleInfo in moduleInfos) {
mi.load();
}
This is a really obscure problem, and I hope this helps anyone else who comes across it.