Loading Flex-based SWFs in AS3-only SWFs

One would think that Adobe would make the integration of Flex-based SWFs and AS3-only SWFs (including those produced by the Flash authoring tool) seamless. Everything works spectacularly if you want to load AS3-only SWFs (or what some folks refer to as Flash SWFs) inside of Flex-based SWFs. But the other way around? Good luck.

In fact, some comments in the Adobe bug database suggest that loading Flex-based SWFs inside of non-Flex-based SWFs is officially unsupported. If so, I'd suggest they change that policy promptly as most of the world still uses non-Flex codebases.

What's the problem? It all revolves around the SystemManager and how it bootstraps Flex-based SWFs. I'll not go into the details, but the problem is that if you don't do things "just so" the SystemManger for your SWF gets confused and doesn't act like the top-level SystemManager that it is.

The fix is easy... down right trivial -- once you know it. It's not in any of the current docs, and Google only leads to a lot of solutions that work if you're not dependent on the SystemManager doing much (such as handling custom cursors or doing complex layout). After lots of stepping through the SystemManager source under different load scenarios I ran across a couple of events (whose names are hard-coded strings in the source) whose purpose was never explained in comments or docs. A bit of Googling revealed this handy doc from the Flex team: Developing and loading sub-applications [PDF]. I couldn't find it's original context nor could I find it navigating the official help docs, so I'm not sure what it's actually a "chapter 1." of (my suspicion is that "chapter 1." is a by-product of their documentation templates).

In the last few pages of that doc they give an example that loads a Flex SWF in a pure AS3 app. Their example is slightly more complicated in that they are trying to load a set of common RPC components to be shared between two potentially different codebases. Our needs are much simpler. Here's all you need to do:

Actionscript:
  1. var loader:Loader = new Loader();
  2. addChild(loader);
  3. loader.load(new URLRequest("my-flex-app.swf"));
  4. loader.addEventListener("mx.managers.SystemManager.isBootstrapRoot", systemManagerHandler);
  5. loader.addEventListener("mx.managers.SystemManager.isStageRoot", systemManagerHandler);
  6.  
  7. function systemManagerHandler(event:Event):void { event.preventDefault(); }

We load the Flex SWF with a Loader, just like normal. We then add two event listeners on our loader (these could probably be on the containing SWF as well as they bubble up). These two events are dispatched by the SystemManager during its initialization phase. If it dispatches these events and nothing happens it makes bad assumptions and gets confused. We need to acknowledge these events. We do this by canceling them (calling event.preventDefault()).

The end result is that your Flex SWF will act completely self-contained. The SystemManager will assume it's the only SystemManager and it will manager everything as if it's the root of the Flex app (which it is).

I've not tested loading multiple Flex SWFs side-by-side with this technique. Due to some singletons (bad, bad singletons!) in the Flex Framework, I'm not sure if this would solve all of your problems as it may not properly coordinate multiple SystemManagers. One solution would be to further wrap the Flex SWF in its own application domain so that there was no cross-pollination of Flex Framework classes.

View Comments

  1. Nice writeup. I’ve mostly been going the other way, but I am sure someday the tables will turn. ;)

  2. What a great find. And what a simple solution. Thanks in advance Troy!

  3. hey, did you ever try to load the Flex App into its own ApplicationDomain? Doesn’t work for me, or is there a trick?

  4. I toyed with that at one time and ended up moving away from it due to some problems, though they may not have been related (I was dealing with several independent integration issues when I had to investigate the above code).

  5. Hi,
    I am trying to load flex app into pure AS3 swfs in currentDomain
    getting problems with custom cursors and tooltips
    made this trick with adding two event listeners
    but it doesn’t help
    any thoughts?

  6. I was having custom cursor issues, tooltip issues and LayoutManager issues, all related to SystemManager issues. The above event listeners are the fix. Also be sure that you add the loader to the stage before you load it (just as I do in the example above) as this ensures the SystemManager finds the stage correctly.

  7. Thanks Men you’ve saved my live !!

  8. Many thanks Troy – this is brilliant! I was having a nightmare with the Flex PopUpManager incorrectly referencing the Flash stage, thus preventing Alerts and Combo boxes from working properly. This worked perfectly and saved me a lot of trouble.

  9. You are an angel

  10. thank you thank you thank you thank you!!

  11. aaaaaaaaaaaaaaaaaa! thank you!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  12. i would never have found this on my own. works like a charm. you just saved me hours & lots of money for my client. thank you so much!

  13. João Rodrigues

    Hello everybody! I'm new with Adobe flex and I'm trying to load the flowplayer media player to one mx:SWFLoader component. When I try to run the application, I have always the error:
    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at org.flowplayer.view::Preloader/stageHasSize()
    at org.flowplayer.view::Preloader/init()

    I don't know how to fix it… Can you help me?

    Thanks!!!

    João Rodrigues

    PS: Sorry my bad bad English!

  14. Oh see, I was close.. I was trying..

    loader.addEventListener(FuckedEvent.FUCKED, initAssRape);

  15. Oh see, I was close.. I was trying..

    loader.addEventListener(FuckedEvent.FUCKED, initAssRape);

  16. Where does this code go? 1st frame? Or on a movie clip?

  17. This was awesome and a huge help however I’m still running into an issue. I have an AS3 project and I want to be able to use the Flex charting and datagrids. If I load a Flex SWF I can’t seem to talk into it. LocalConnection seems to fail also. Is there anyway to load the SWF and talk to it or at least load the libraries needed for the components into an AS3 project? Thanks I have been trying for days to figure this out.

Leave a comment

blog comments powered by Disqus