Using ActionScript 2 SWFs with Flex 2

Introduction

One of the benefits of the Flash Player technology is being able to write applications in the manner that best suits you. For example, you can use Flash 8 to develop high-impact animations or use Flex to build compelling business applications.

What is even better is being able to combine them together. It turns out that creating an animiation in Flash and incorporating it into a Flex application is not uncommon. And because both Flex and Flash are language driven via ActionScript, the Flex application could control the Flash animiation or vice-versa.

Doing this with Flash 8, Flash MX 2004 or Flash MX and Flex 1.5 was relatively easy. But that is not the case with Flex 2 and Flash Player 9. I’ll show how to do this and I hope you see that this is in fact, a better way to do it.

As you may know, a Flex 2 SWF requires Flash Player 9. That’s because Flex 2 uses ActionScript version 3 (AS3) and Flash Player 9 was developed (from the ground up, I’m told) to use ActionScript 3. ActionScript 3 with its stronger data typing and object-oriented structure provides a better platform for a higher performing Flash Player.

But as with all versions of the Flash Player, Flash Player 9 is backward-compatible. That is, it will run SWFs built for earlier Flash Player versions. But this happens differently than before. When the Flash Player 9 loads a SWF that uses ActionScript 2 (or less), it creates a virtual machine – a self-contained area which is loaded with the logic to run ActionScript 2 SWFs. We call this an AVM. When Flash Player 9 has loaded a Flex 2 SWF which then requests to load an AS2 SWF, that SWF is loaded into its own AVM. Thus the two SWFs run in different areas of the Flash Player. Different and isolated areas.

What this means is that your Flex 2 application cannot address the AS2 SWF and reach inside and reference its functions, variables, and timeline. Likewise, the AS2 SWF cannot get at anything in the Flex 2 application simply by referencing it.

The solution is to use LocalConnection – the Flash Player to Flash Player messaging system. If you haven’t used LocalConnection before, take a moment and read up on it. You might get some inspiration for your next project.

To see a demonstration of this, click this link: Flex 2 and Flash Demo and be sure your browser has Flash Player 9. This will open in a new window.

Download source here

Briefly, LocalConnection lets one Flash Player send messages to one or more other Flash Players running on the same desktop. The Flash Players can be on the same HTML page, in different frames, or even in different browsers. For example, suppose you are creating an HTML page with 3 frames: a top one for a banner, a side one for a menu, and a center one for content. You want to have the banner and menu be Flash movies. You’d also like any selection from the menu SWF change the content of the banner SWF. Since these SWFs are running inside of different Flash Players, you can use LocalConnection to have the menu SWF send messages to the banner SWF.

LocalConnection is a one-way message. One SWF listens for messages that another SWF sends. If you want bi-directional communication, both SWFs need to create LocalConnections and name them uniquely.

LocalConnection also works between Flash Player 9 AVMs.

Flash

In your Flash application create a LocalConnection object and add to it functions that you want the Flex application to call. These are the ‘messages’ I’ve been mentioning.

var fromFlex_lc:LocalConnection = new LocalConnection();

fromFlex_lc.stopMe = function() { stop(); }
fromFlex_lc.playMe = function() { play(); }

fromFlex_lc.connection( "lc_from_flex" );

The stopMe and playMe functions are very simple and just stop and play the timeline. But they can of course, be much more complex. Flex is going to invoke them when the user clicks a button.

Flex

In your Flex application, create a LocalConnection object and use it to invoke the stopMe and playMe functions in the Flash SWF.

import flash.net.LocalConnection;

var toFlash_lc:LocalConnection = new LocalConnection();

<mx:Button label="Stop" click="toFlash_lc.send('lc_from_flex', 'stopMe')" />
<mx:Button label="Play" click="toFlash_lc.send('lc_from_flex', 'playMe')" />

The buttons invoke the LocalConnection.send() method, naming the connection that the Flash SWF is listening on. The second argument to the send() method is the name of the function to invoke. If the functions have any arguments, they follow the method name.

Flash to Flex

As you might expect, having the Flash SWF send messages to the Flex SWF is just the reverse. And that is true with the exception of where you define the messages the LocalConnection.send() method invokes.

In the Flex application you create an object which has the functions you want invoked from the LocalConnection. For example:

<mx:Application xmlns:mx="..." initialize="initApp()" >
<mx:Script>
<![CDATA[
import flash.net.LocalConnection;

public function showDetails() : void {
// do something
}

private var fromFlash_mc:LocalConnection;

private function initApp() : void {
fromFlash_lc = new LocalConnection();
fromFlash_lc.client = this;
fromFlash_lc.connect("lc_from_flash");
}
]]>
</mx:Script>
...
</mx:Application>

The Flash SWF can now invoke any public method defined on the object named as the “client” to the LocalConnection. In this case the intent is to have the Flash SWF invoke the showDetails() method.