SWF to SWF Communication in FLASH CSx:
how to call methods between swf files
Two of the most popular questions when loading SWF files in Flash CSx / AS3 are:
- how to call a method in the loaded swf from the Main document class
- how to reference at the main document class to call a method from the the loaded swf.
In this post I’ll provide you a quick and easy sample to cover both situations.
This is not the best way to accomplish this task but it’s very easy to understand and use.
So what we’ll do?
1) We’ll load the file Page.swf inside Main.swf clicking on the LoadSwf Button
2) When loading is completed we’ll enable the Call Method inside SWF button
3) Clicking on this button we’ll call a method inside Page.as Document Class. In few words, we’ll move a MovieClip inside the loaded page from the main.fla
4) From the loaded swf (Page.fla) we’ll call a method inside the Main Document Class clicking on the Orange Rectangle button. This method will remove from displayList the loaded swf
Here a Live Demo (click on Buttons to see how it works):
CREATE THE .FLA FILES:
We first create a new Flash AS3 File, main.fla, with two Button Components (see image below).
We’ll create in the next paragraph its document Class called Core.as.
The second step is create the loaded page, page.fla.
It will contain only a MovieClip (an orange Rectangle), with istance name: btn. See image below

Following the full-commented Document Classes:
Core.as (linked to Main.fla)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | package { import flash.display.Loader; import flash.display.MovieClip; import flash.display.DisplayObjectContainer import flash.events.Event; import flash.events.MouseEvent; import flash.events.IOErrorEvent; import flash.net.URLRequest; public class Core extends MovieClip { private var loader:Loader; private var loaderContent:Object; /** * Constructor */ public function Core () { callSwfMethodBtn.enabled = false; // Load SWF button loadSwfBtn.addEventListener(MouseEvent.CLICK, loadSwf) // Call method inside the loaded SWF (this button will be enabled after the SWF loading) callSwfMethodBtn.addEventListener(MouseEvent.CLICK, callExternalMethod) } /** * Load the SWF */ public function loadSwf(e:MouseEvent=null) { if (loader == null){ loader = addChild(new Loader()) as Loader; loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler); loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler); loader.load(new URLRequest("Page.swf")); } } /** * Unload the SWF */ public function unloadSwf() { trace ("doSomething on Core.as (Main.fla)"); callSwfMethodBtn.enabled = false; loader.unload(); loader = null; } /** * Invoked when SWF is loaded */ private function completeHandler (e:Event) { trace ("SWF Loaded!"); // Enabled 'call Swf method' button callSwfMethodBtn.enabled = true; // Save SWF content Reference loaderContent = e.currentTarget.content; } /** * Invoked if there are some loading swf issues */ private function errorHandler (e:IOErrorEvent) { trace ("Unable to load SWF"); } /** * Call methods inside the loaded swf */ private function callExternalMethod(e:MouseEvent):void { // Call moveButton() method inside the loaded swf using the loaderContent reference // NOTE: it will move the orange Rectable) loaderContent.moveButton(); } } } |
Page.as (linked to Page.fla)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | package { import flash.display.MovieClip; import flash.events.MouseEvent; import fl.transitions.Tween; import fl.transitions.easing.*; public class Page extends MovieClip { /** * Constructor */ public function Page () { // Enable CLICK event on the Orange Rect Button btn.buttonMode = true; btn.addEventListener(MouseEvent.CLICK, destroyMe) } /** * Move the button with a Tween animation * NOTE: this method IS CALLED FROM the Main.fla Document Class (Core.as) */ public function moveButton():void { var myTween:Tween = new Tween(btn, "x", Elastic.easeOut, 0, 200, 1.5, true); } /** * Unload the Swf * NOTE: this method CALLS the 'unloadSwf' method inside the Main.fla document class (Core.as) */ private function destroyMe(e:MouseEvent):void { // Call a method on the root swf (root.loaderInfo.loader.root as Object).unloadSwf(); } } } |










Ottimo tutorial, incredibilmente chiaro.
Tuttavia, mi sapresti dire perché nella riga 39 di Page.as hai usato
(root.loaderInfo.loader.root as Object).unloadSwf();
piuttosto che:
(root.loaderInfo.loader.root as MovieClip).unloadSwf();
dato che Page.as deriva proprio da MovieClip.
Ciao
You are absolutly right!!
MovieClip was the best choice in this situation (i just used Object to cover all the possible situations, i.e. if you load an swf inside a Sprite)
However thanx for your comment. It’s the first one
and sorry if i’m answering you in english but i’m trying to port my blog in this language (even if my English is not so good ; )
Fabio
Thank you very much, henceforth I will post only in English.
Bye
Pretty clean solution. I think this is the best thing you can do to make it work quickly and effectively, although I am also considering an event based solution but I guess one can settle at this too :).
Very nice, clean code. I have a few notes to point out
1. be sure to use “loader.contentLoaderInfo” and NOT “loader.loaderInfo”
If you use “loaderInfo”, on line 73 you will find that e.currentTarget.content is actually “Core”. Using “contentLoaderInfo” will give you “Page” as expected.
2. Use namespaces or a new application domain
Since both your SWFs have the default package (none), all your code from the loaded SWF will be loaded into the loading SWF. If your main classes have the same name in both, there will be a name collision and your LOADED SWF will use the code from the LOADING SWF.
This can manifest in several ways, but usually just in massive amounts of confusion. If you try to load a SWF in your addedToStage handler, you’ll find yourself in an infinite recursion.
The first solution is to use namespaces. This ensures that if you have any classes with the same names that there are no name collisions (and no infinite recursion, and no mysterious behaviors). This solution is acceptable. However, the classes that you load will NOT unload when your unload the loaded SWF. And if you don’t control your LOADED (Page) SWFs, you can’t guarantee the safety of your Core application.
The second (and better) solution is to use a new application domain for your loaded SWF. This completely isolates the code that you’re loading, ensures there are no name collisions, and saves you a ton of headache. Your code then changes to this:
loader.load( new URLRequest(”Page.swf”), new LoaderContext(false, new ApplicationDomain()));
Cheers,
cm
Leave your response!
Archives
Categories
Blogs
3D ActionScript Adobe AIR AIR for Android android Arduino Binding burrito hero 4.5 TabbedMobileApplication Chat Chrome Cocomo code optimization components custom/generic components custom components DataList developer central Emitter FLARToolkit Flash Flash Builder Flex HTTPService illustrator Infrared Interactions itemRenderer Joystick Loader mobile Papervision PHP Rss Servo singleton Skin Skinning Transitions Tween URLLoader URLRequest Vertical Scrollbar VScrollbar youtube
WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better.
Recent Posts
Develop Mobile apps with Catalyst?
Code optimization
TextInput Component
Interactions and Transitions
Most Commented
Recent Comments
how to call methods between swf files