Communication between ActionScript and the container application
can take one of two forms: either ActionScript can call code (such
as a JavaScript function) defined in the container, or code in the
container can call an ActionScript function that has been designated
as being callable. In either case, information can be sent to the
code being called, and results can be returned to the code making
the call.
To facilitate this communication, the ExternalInterface class
includes two static properties and two static methods. These properties
and methods are used to obtain information about the external interface
connection, to execute code in the container from ActionScript,
and to make ActionScript functions available to be called by the
container.
Getting information about the external container
The
ExternalInterface.available
property
indicates whether the current Flash Player is in a container that
offers an external interface. If the external interface is available,
this property is
true
; otherwise, it is
false
. Before
using any of the other functionality in the ExternalInterface class,
you should always check to make sure that the current container
supports external interface communication, as follows:
if (ExternalInterface.available)
{
// Perform ExternalInterface method calls here.
}
Note:
The
ExternalInterface.available
property
reports whether the current container is a type that supports ExternalInterface
connectivity. It doesn’t tell you if JavaScript is enabled in the
current browser.
The
ExternalInterface.objectID
property allows
you to determine the unique identifier of the Flash Player instance
(specifically, the
id
attribute of the
object
tag
in Internet Explorer or the
name
attribute of the
embed
tag
in browsers using the NPRuntime interface). This unique ID represents
the current SWF document in the browser, and can be used to make
reference to the SWF document—for example, when calling a JavaScript
function in a container HTML page. When the Flash Player container
is not a web browser, this property is
null
.
Calling external code from ActionScript
The
ExternalInterface.call()
method
executes code in the container application. It requires at least
one parameter, a string containing the name of the function to be
called in the container application. Any additional parameters passed
to the
ExternalInterface.call()
method are passed
along to the container as parameters of the function call.
// calls the external function "addNumbers"
// passing two parameters, and assigning that function's result
// to the variable "result"
var param1:uint = 3;
var param2:uint = 7;
var result:uint = ExternalInterface.call("addNumbers", param1, param2);
If the container is an HTML page, this method invokes the JavaScript
function with the specified name, which must be defined in a
script
element
in the containing HTML page. The return value of the JavaScript
function is passed back to ActionScript.
<script language="JavaScript">
// adds two numbers, and sends the result back to ActionScript
function addNumbers(num1, num2)
{
return (num1 + num2);
}
</script>
If the container is some other ActiveX container, this method
causes the Flash Player ActiveX control to dispatch its
FlashCall
event.
The specified function name and any parameters are serialized into
an XML string by Flash Player. The container can access that information
in the
request
property of the event object and
use it to determine how to execute its own code. To return a value
to ActionScript, the container code calls the ActiveX object’s
SetReturnValue()
method,
passing the result (serialized into an XML string) as a parameter
of that method. For more information about the XML format used for
this communication, see
The external API’s XML format
.
Whether the container is a web browser or another ActiveX container,
if the call fails or the container method does not specify a return
value,
null
is returned. The
ExternalInterface.call()
method
throws a SecurityError exception if the containing environment belongs
to a security sandbox to which the calling code does not have access.
You can work around this by setting an appropriate value for
allowScriptAccess
in
the containing environment. For example, to change the value of
allowScriptAccess
in
an HTML page, you would edit the appropriate attribute in the
object
and
embed
tags.
Calling ActionScript code from the container
A container can only call ActionScript code that’s in a function—no
other ActionScript code can be called by a container. To call an
ActionScript function from the container application, you must do
two things: register the function with the ExternalInterface class,
and then call it from the container’s code.
First, you must register your ActionScript function to indicate
that it should be made available to the container. Use the
ExternalInterface.addCallback()
method,
as follows:
function callMe(name:String):String
{
return "busy signal";
}
ExternalInterface.addCallback("myFunction", callMe);
The
addCallback()
method takes two parameters.
The first, a function name as a String, is the name by which the
function will be known to the container. The second parameter is
the actual ActionScript function that will be executed when the
container calls the defined function name. Because these names are
distinct, you can specify a function name that will be used by the
container, even if the actual ActionScript function has a different
name. This is especially useful if the function name is not known—for
example, if an anonymous function is specified, or if the function
to be called is determined at run time.
Once an ActionScript function has been registered with the ExternalInterface class,
the container can actually call the function. How this is done varies according
to the type of container. For example, in JavaScript code in a web browser,
the ActionScript function is called using the registered function
name as though it’s a method of the Flash Player browser object
(that is, a method of the JavaScript object representing the
object
or
embed
tag).
In other words, parameters are passed and a result is returned as
though a local function is being called.
<script language="JavaScript">
// callResult gets the value "busy signal"
var callResult = flashObject.myFunction("my name");
</script>
...
<object id="flashObject"...>
...
<embed name="flashObject".../>
</object>
Alternatively, when calling an ActionScript function in a SWF
file running in a desktop application, the registered function name
and any parameters must be serialized into an XML-formatted string.
Then the call is actually performed by calling the
CallFunction()
method
of the ActiveX control with the XML string as a parameter. For more
information about the XML format used for this communication, see
The external API’s XML format
.
In either case, the return value of the ActionScript function
is passed back to the container code, either directly as a value
when the caller is JavaScript code in a browser, or serialized as
an XML-formatted string when the caller is an ActiveX container.
The external API’s XML format
Communication between ActionScript
and an application hosting the Shockwave Flash ActiveX control uses
a specific XML format to encode function calls and values. There
are two parts to the XML format used by the external API. One format
is used to represent function calls. Another format is used to represent
individual values; this format is used for parameters in functions
as well as function return values. The XML format for function calls
is used for calls to and from ActionScript. For a function call
from ActionScript, Flash Player passes the XML to the container;
for a call from the container, Flash Player expects the container
application to pass it an XML string in this format. The following
XML fragment shows an example XML-formatted function call:
<invoke name="functionName" returntype="xml">
<arguments>
... (individual argument values)
</arguments>
</invoke>
The root node is the
invoke
node. It has two
attributes:
name
indicates the name of the function
to call, and
returntype
is always
xml
.
If the function call includes parameters, the
invoke
node
has a child
arguments
node, whose child nodes will
be the parameter values formatted using the individual value format
explained next.
Individual values, including function parameters and function
return values, use a formatting scheme that includes data type information
in addition to the actual values. The following table lists ActionScript
classes and the XML format used to encode values of that data type:
ActionScript class/value
|
C# class/value
|
Format
|
Comments
|
null
|
null
|
<null/>
|
|
Boolean
true
|
bool true
|
<true/>
|
|
Boolean
false
|
bool false
|
<false/>
|
|
String
|
string
|
<string>string value</string>
|
|
Number, int, uint
|
single, double, int, uint
|
<number>27.5</number>
<number>-12</number>
|
|
Array (elements can be mixed types)
|
A collection that allows mixed-type elements, such
as ArrayList or object[]
|
<array>
<property id="0">
<number>27.5</number>
</property>
<property id="1">
<string>Hello there!</string>
</property>
...
</array>
|
The
property
node defines
individual elements, and the
id
attribute is the numeric,
zero-based index.
|
Object
|
A dictionary with string keys and object
values, such as a HashTable with string keys
|
<object>
<property id="name">
<string>John Doe</string>
</property>
<property id="age">
<string>33</string>
</property>
...
</object>
|
The
property
node defines
individual properties, and the
id
attribute is
the property name (a string).
|
Other built-in or custom classes
|
|
<null/> or
<object></object>
|
ActionScript encodes other objects as null or
as an empty object. In either case any property values are lost.
|
Note:
By way of example, this table shows equivalent
C# classes in addition to ActionScript classes; however, the external
API can be used to communicate with any programming language or
run time that supports ActiveX controls, and is not limited to C#
applications.
When you are building your own applications using the external
API with an ActiveX container application, you’ll probably find
it convenient to write a proxy that will perform the task of converting
native function calls to the serialized XML format. For an example
of a proxy class written in C#, see Inside the ExternalInterfaceProxy
class.
|
|
|