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.

  • http://www.pushbuttonengine.com/ Ben Garney

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

  • Zach Foley

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

  • http://www.formatlos.de Martin

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

  • http://troygilbert.com/ Troy

    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).

  • http://blog.go4flash.com Antonos

    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?

  • http://troygilbert.com/ Troy

    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.

  • KissCoool

    Thanks Men you’ve saved my live !!

  • Tegs

    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.

  • dk

    You are an angel

  • Kiely

    thank you thank you thank you thank you!!

  • vlad121212

    aaaaaaaaaaaaaaaaaa! thank you!!!!!!!!!!!!!!!!!!!!!!!!!!!!

  • http://www.nigam.biz/ Nigam Shah

    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!

  • 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!

  • http://www.theHuston.com/ theHuston

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

    loader.addEventListener(FuckedEvent.FUCKED, initAssRape);

  • http://www.theHuston.com/ theHuston

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

    loader.addEventListener(FuckedEvent.FUCKED, initAssRape);

  • Dragon

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

  • Llamajuana

    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.

  • Walt

    Yes.

    Where exactly should this code live?

  • Walt

    Does anyone know where this code should be placed?

  • http://www.facebook.com/profile.php?id=545933705 Thijs Triemstra

    Thanks for the code example, and especially the link to that Adobe PDF, very useful.

  • http://www.facebook.com/profile.php?id=100000261634981 Christian Hünerfauth

    great mate thx for sharing !

  • Pepperworldwide

    thx for sharing :)

  • http://twitter.com/ExtremeBt Nikola Vojnovski

    Thanks for the sharing! Is there any way to interact with button in flex-based swf? for example: Load the flex based swf into flash swf, click on the flex button and get the action in flash? Thanks

  • http://twitter.com/ExtremeBt Nikola Vojnovski

    Thanks for the sharing!
    Is there any way to interact with button in flex-based swf? For example: Load the flex based swf into flash swf, click on the flex button and get the action in flash? Thanks

  • Owen

    Hello, thank you for the article. It seems to be the only one on the entire internet that focuses on this issue. I have a Flex 4.5 SWF that I’m trying to load into a Flash Pro CS5 SWF, but it just comes up black. I tried using your method here, but it’s not working for me. The output I get in Flash just says “file type is
    application/x-shockwave-flash” and the loaded SWF is black. I get none
    of the traces I put into the Flex SWF. Someone on the Adobe forum suggested I set the library linkage to RSL, but I’m still having the issue. Can you help me? Thanks.

  • Owen

    Never mind, I got it! I was publishing with an older version of Flash Player 10 in Flash Pro. Great article, thanks again!