Interfacing between Flash 8 & 9 - Problems and Solutions

Filed under: Articles — Robert Taylor at 8:33 am on Tuesday, November 14, 2006

In order to appreciate the thought and time that went into the final solution, it is first and foremost important to understand:

  • What is the problem?
  • How it will affect your past and future projects?
  • What options are available?
  • Why FlashInterface is the best solution?

A Brief Overview

We all know Flash is an amazing tool for both designing interactive media and developing Rich Internet Applications (RIA). Over the past decade, Adobe (formerly, Macromedia) has done a great job at enhancing the player while keeping compatible with previous player versions (no small task). However, like most things, there are only so many new enhancements that you can add before it is time to do a “do-over”. Think of it like this. You could keep extending the life of your computer by upgrading the memory or hard drive, perhaps a better video card. But as more time elapses, it profits you less to do the upgrades and more to purchase a new computer. The same is true of software.

There is no doubt that Adobe has a vision for the Flash platform with the emergence of Flex 2, Apollo, and other Flash platform-related technologies. In order to help their customers (us) move to the next level of development, Adobe felt it was time to “buy a new computer” with the release of the next major release of the Flash player. The Flash 9 player is no mere upgrade. It’s a new virtual machine, with faster processing, Just-In-Time (JIT) compiling and cross-platform support (including Windows, Macintosh OS, and Linux). Lets talk a little more about the virtual machine.

What is a virtual machine?

“A virtual machine is a piece of computer software that isolates the application being used by the user from the computer. Because versions of the virtual machine are written for various computer platforms, any application written for the virtual machine can be operated on any of the platforms, instead of having to produce separate versions of the application for each computer and operating system. The application is run on the computer using an interpreter or Just In Time compilation.” – wikipedia.com, “Application virtual machine”

In laymen’s terms, the Flash player is a virtual machine. It handles the hard part of talking to the different platforms*, which means we (as developers) only worry about developing for the Flash player. Our Flash files (FLAs) and ActionScript (AS) get compiled into byte code (SWFs) that is then read by the player and interpreted. Voila! we now have a bouncing ball on the screen. Admit it, I know you have one somewhere in your archives.

*Platforms may consist of both software (such as operating systems) and hardware (such as the type of processor the code is executed through).

Flash ActionScript Virtual Machine (AVM)

No matter what kind of tires or gas you use in your car, if you don’t replace the engine, it just isn’t going to go any faster. The same is true of the Flash player. For the past decade, Adobe (formerly Macromedia) has been pimping the heck out of the Flash player, and we thanked them for it (most of the time, there was that incident with Flash 7 but we lay that one to rest). However, the Flash player was still running with the same engine. The Flash player team was pretty good at finding ways to tweak it here and there (proven in Flash 8) to make it perform pretty well. But we all knew what we really wanted. We wanted to build applications for the web, like those that we have on our desktop. Adobe also wants us to build those applications, so they put a new engine or ActionScript Virtual Machine (AVM) in the player. Actually, they put a second AVM in the player. Imagine two engines in your car; crazy as well as impressive!

Why do we need two virtual machines? To keep compatible with previous Flash player versions. I doubt any of us would have been too pleased if Adobe announced the new Flash player would not support any of our old SWFs! I can see the burning Adobe corporate office now. Fortunately, we don’t have to worry about that scenario. The fact is, we have two AVMs – AVM1 supports Flash 8 and lower; AVM2 will support Flash 9 and higher. When I heard this, my thought was, “This is great news! I can guarantee that anything I build in Flash 8 will not break with the next release of the Flash player!” What do we have to do each time a new Flash player is about to be released? Check and make sure all our published SWFs still work. Sure we will have to do that for Flash 9 and higher projects, but as I continue to use and create Flash 8 SWFs, I know exactly what I can expect from now on.

Defining the Problem…

So now that we understand that the Flash 9 Player consists of two ActionScript Virtual Machines (AVM), lets now discuss the problem. The problem is the AVMs don’t have a direct way to communicate with each other. When we only had one AVM, you could load one SWF into the other and treat that SWF as part of the original application. This is because both SWFs still resided inside of the same environment or virtual space. Think of it like running two applications on the same computer, most of our applications can natively interact in some form or another with other applications (even if its just using the clipboard). Now, you buy a second computer… copying and pasting between the two computers is not going happen. As long as you run your apps in one virtual space or the other, you are fine. However, as soon as you need the apps to interact across spaces, it takes a little more work.

How does this affect you?

With the release of the Flash 9 player, we can now build the next generation of Flash applications with tools such as Flex 2 Builder and the upcoming Flash CS3. But, I am willing to bet that we all have or will still use elements that have been developed in AS 2.0 and published for the Flash 8 player or lower. Or perhaps you are working on a Flex project for a client who can’t afford the expense of porting all of their intellectual property to the new AVM. We will all be affected by this for some time. There isn’t anything wrong with it because it is just a part of existing in the development world. The real question we have to ask ourselves is, “Is there a way to overcome the problem?” and “What are our options?”. It would be pointless to write this article if I didn’t have a solution, or two. We will discuss the alternatives in the next section.

Defining the Solution

In order to discuss solutions, it is important to define what we would like to solve. Here is an outline of the things I wanted in the solution:

  • Bi-directional communication between AVMs
    • Flash 9 can talk to Flash 8
    • Flash 8 can talk to Flash 9
  • Synchronous communication – Ability to receive return values without the need of a callback.
  • Simple and intuitive API for communicating
  • Call both properties and methods
  • Anonymous calls through some form of registration process – allows you to talk to objects, methods and properties without knowing the location of the item within the SWF.
  • Optional user-defined API or global access to SWF
  • Event Listener model as well as direct connection.
  • No limitation on the amount of data that was passed between AVMs.
  • Ability to pass common data types (Booleans, Numbers, Strings, Objects, Arrays)

Yeah. I know. Those were the same things you were thinking too! Moving on…

What solutions are available?

If we need to share data between two computers, we have several options. The most common means is to use the Internet. Through the web, we can even share data almost instantly. Examples are chats, online gaming and file sharing to name a few.

Option 1 - LocalConnection

We have a similar option within Flash to communicate between the our two AVMs, known as LocalConnection. LocalConnection permits two or more SWFs to communicate with each other regardless of their scope. In other words, I can have a SWF reside on my desktop and another in my browser and they can both “talk” to each other through a user defined API. So, having dealt with LocalConnection in the past, it felt like this might be the appropriate direction to solve our problem. Interfacing through LocalConnection is fairly simple. And I have seen several blogs post this solution as well on their website in order to overcome this hurdle. However LocalConnection has several limitations that prevent us from achieving our definition above, lets talk about a few of the major ones.

Limitations:

  1. No synchronous communication

LocalConnection will allow us to achieve our first goal, which is communicate between our Flash 9 and 8 SWFs. However, we could never do it synchronously, meaning we would always have to pass a callback. Now I have developed some pretty creative approaches in the past to limiting the amount of callbacks needed, but the solutions still doesn’t allow me to just ask, what is the x and y position of this element on the screen.

  1. Limitation in file size

LocalConnection has a limit in file size. There is nothing in the documentation that tells us exactly what the size limit is. However I know that I have hit it in the past. The way to get around this is to distribute your data in chunks. Having done this for a few projects, it does take some time to get large data passed when doing it in chunks of data. Also if you do happen to hit the size limit, LocalConnection gracefully dies without any warnings (not so graceful).

  1. Limitation on data types

Strings and Numbers are the only common data types supported. You can overcome through a serialize / desterilize solution such as JSON. But this will increase the file size and overall load of the solution.

  1. Unexpected connections

This one seems to be a common one in the forums. Sometimes you lose your connection when using LocalConnection. You can remedy this one by checking your connection through some dummy call, but I personally don’t like having to do this.

Though there are limitations to LocalConnection, you can create some pretty creative work-a-rounds to them, as I explained with each limitation. However, there is another solution that allows us to achieve all of our goals.

Option 2 – ExternalInterface

ExternalInterface was introduced with the release of the Flash 8 player. It allows us to communicate “directly” to JavaScript and vice-versa. The communication is synchronous and there are many power things that you can do as a result. One of them being, that if two SWFs had a common API to communicate with each other through ExternalInterface, they could talk back and forth as if they were native to each other. If we look at what ExternalInterface offers compared to our requirements, it offers more of th.

LocalConnection

ExternalInterface

Bi-direction communication between AVMs

X

X

Synchronous calls

X

Returns values from within same call

X

Common API*
User-Defined API

X

X

Call Local Properties
Call Local Methods
Anonymous Calls

X

X

Global Access to SWF elements
Optional Event Listener Model
No limitation on data size

X

Supports Booleans

X

Supports Numbers

X

X

Supports Strings

X

X

Supports Arrays

X

X

Supports Objects

X

X

* There is no common API in the sense that the user is required define the accessible methods when using ether LocalConnection or ExternalInterface.

Though ExternalInterface doesn’t natively support our entire solutions, it does provide us with some key elements that we would like to have, namely:

  • Synchronous calls
  • Return values
  • Commonly supported data types

As far as the others, I knew I could construct a set of classes to achieve the other requirements.

Option 3 – FlashInterface – Why it’s better than the rest!

FlashInterface provides the complete solution. It allows us to communicate between AVMs directly with a common API that exists in ActionScript 2.0 and 3.0. It is pointless to show the comparison chart because all the above items would be checked.

FlashInterface can also support accessing and controlling Flash 7 and lower SWFs through a Flash 8 wrapper. You will see in the tutorials all the different means to using and supporting hybrid Flash applications that have a mix of Flash 8 and 9 technologies. The greatest thing about FlashInterface is that is it free, so let others know about this solution.

Visit the FlashInterface page for downloads, examples, and tutorials.

14 Comments »

568

Comment by Diego Volpe

November 14, 2006 @ 1:35 pm

I don´t think I can use FlashInterface to load a swf(avm1) inside another swf(avm2). Is That right?

569

Comment by Robert Taylor

November 14, 2006 @ 2:14 pm

No, that would not be possible with any solution.

682

Comment by Tim

November 22, 2006 @ 11:08 am

Robert would it be possible to post the full source for the examples? I haven’t been able to get this working with a sample Flex project and Flash 8 swf. Some of the examples seem to differ a bit in how they use the API. I’ve seen references to setting a swfId as well as a flashId. Working source code would be very helpful.

699

Comment by Robert Taylor

November 23, 2006 @ 10:50 am

Yes, I hesitated to provide it originally because of the file size, but I will put it up, until it become too much of a burden on my server bandwidth. Will have it available within the next couple of days.

729

Comment by Tim

November 25, 2006 @ 5:57 pm

I appreciate it! Once I get my own working example I’ll post it online (with source) to help add more examples.

739

Comment by Robert Taylor

November 27, 2006 @ 8:30 am

Okay. Example Source Files are now available http://www.flashextensions.com/products/flashinterface.php.

751

Comment by Tim

November 29, 2006 @ 3:40 pm

Thanks for the examples, they’ve helped get me going in the right direction. I’m calling methods in a flash 8 movie from a flex app ok, but I’m still having a bit of trouble with event dispatching. It’s unclear from the documentation on which id’s you’re supposed to use on each side of the event. It looks like my flex app sets a listener using it’s own id and the flash 8 movie dispatches an event using the id of the flex app?

I could come up with a small test case and post it online to get some feedback.

892

Comment by Joa

December 8, 2006 @ 9:36 am

I did this some while ago and instead of using a global class I am using a proxy class. So I get also rid of the whole referencing names you have to use and it is much better to integreate into the whole DOM3 model.

Comment by amdenis

July 12, 2007 @ 10:37 am

Despite the extra effort (which is great to avoid when one can), I have had great luck with custom mediator pattern approaches, and was wondering if your solution adddresses some of the same issues.

I am reviewing what you created, and can appreciate the value of it, but have not yet dug into your implentation yet.

The quesiton is whether you designed it to address common issues that can be overcome by custom mediator patterns, of which you can refer to at the following url for specifics:
http://jessewarden.com/2007/05/controlling-flash-player-8-swfs-in-flash-player-9-swfs.html

If so, do you have examples of how to load and control Flash 8 content into Flex/Flash9 in a way that becomes synchronously and async controllable (obviously, SWFLoader does not provide the necessary abstraction and API for this, which together with the other common issues is why I normally go with custom mediator implementations)?

Comment by diamondtearz

July 15, 2007 @ 7:25 pm

Thanks for a really useful tool. once I got my code working I was impressed by the ease with which communication could be achieved. I have a worry about the performance hit if any that would be caused by having 2 AVMs running at the same time in the swf. Have you had any experience or encountered any information on that?

Thanks,
Mani

Comment by Robert Taylor

July 16, 2007 @ 9:18 am

I have used it in several programs now for various things and have not seen a performance hit and do not shy away from using it. Feel free to do a benchmark test and post the results.

Rob

Comment by raulpopa

August 1, 2007 @ 8:21 am

I just found this approach from the gskinner’s blog, where we were discussing about his SWFBridge and our ActionScriptBridge, actually similar products to this Interface.

I was wondering if your method works ok when the same page is opened multiple times, and the same swf loads multiple times inside different AS3.0 projects… the connection would fail? If not, how did you managed this?
And, do you have any idea of how can you manage to return a delayed return as the caller method return statement?

Comment by abolin

August 7, 2007 @ 5:34 am

Hi,

has anyone expirienced problems in firefox?

following the 2. video on your site, I encountered

2 Security Errors: #2060 #2140 in Firefox, in IE it worked fine.

I am using Flex Builder 2.0.155577
In the video they opened the example appl. in firefox without problems…

Comment by yaunato

September 27, 2007 @ 8:26 am

Good comparison of LocalConnection vs. ExternalInterface approaches, but you left out the details of FlashInterface mechanisms. For those who haven’t the time to download and inspect the classes:

FlashInterface uses ExternalInterface to inject Javascript into the host application via eval() and therefore does not require preexisting Javascript. The Javascript acts as a hub and provides flashplayer embed id’s to Actionscript.

FlashInterface maintains id’s for each instance, whether AS2 or AS3 or in different embedded swf’s, making them uniquely addressable.

Although useful, this is still insufficient for my purposes since it has the same limitations as any ExternalInterface-Javascript solution. For example, it does not function outside of a Javascript-enabled host application or between the browser and standalone app).

Lawrence

RSS feed for comments on this post.

Leave a comment

You must be logged in to post a comment.