Использование класса ExternalInterface

Flash Player 9 и более поздних версий, Adobe AIR 1.0 и более поздних версий

Обмен данными между ActionScript и приложением контейнера может принимать две формы: ActionScript может вызвать код (как в функции JavaScript), определенный в контейнере, либо код в контейнере может вызвать функцию ActionScript, которая была разработана с учетом возможности вызова. В любом случае информацию можно отправить к вызываемому коду, а результаты вернуть коду, который совершил вызов.

Чтобы упростить обмен данными, класс ExternalInterface включает два статических свойства и два статических метода. Эти свойства и методы используются для получения информации о подключении внешнего интерфейса, для выполнения кода в контейнере из ActionScript и для того, чтобы функции ActionScript можно было бы вызвать с помощью контейнера.

Получение сведений о внешнем контейнере

Свойство ExternalInterface.available указывает, находится ли текущий Flash Player в контейнере, имеющем внешний интерфейс. Если внешний интерфейс имеется, свойство принимает значение true ; в противном случае — false . Перед использованием любых других функций в классе ExternalInterface необходимо всегда проверять, что текущий контейнер поддерживает обмен данными с внешним интерфейсом. Это делается следующим образом:

if (ExternalInterface.available) 
{ 
    // Perform ExternalInterface method calls here. 
}
Примечание. Свойство ExternalInterface.available говорит о том, принадлежит ли текущий контейнер типу, поддерживающему возможность подключения ExternalInterface. Оно не информирует о том, включен ли JavaScript в текущем обозревателе.

Свойство ExternalInterface.objectID позволяет определить уникальный идентификатор экземпляра Flash Player (особенно атрибут id тега object в Internet Explorer или атрибут name тега embed в обозревателях с помощью интерфейса NPRuntime). Этот уникальный идентификатор представляет текущий SWF-документ в обозревателе. Его можно использовать для ссылок на SWF-документ (например, при вызове функции JavaScript на странице HTML контейнера). Когда контейнер Flash Player не является веб-обозревателем, этому свойству присваивается значение null .

Вызов внешнего кода из ActionScript

Метод ExternalInterface.call() выполняет код в приложении контейнера. Он требует наличия по крайней мере одного параметра (строки, содержащей имя функции, которую необходимо вызвать в приложении контейнера). Любые дополнительные параметры, переданные методу ExternalInterface.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);

Если контейнер является страницей HTML, этот метод запускает функцию JavaScript с указанным именем, которая должна быть определена в элементе script на той странице HTML, где он содержится. Возвращаемое значение функции JavaScript передается обратно в ActionScript.

<script language="JavaScript"> 
    // adds two numbers, and sends the result back to ActionScript 
    function addNumbers(num1, num2) 
    { 
        return (num1 + num2); 
    } 
</script>

Если контейнер находится в каком-либо другом контейнере ActiveX, этот метод заставляет элемент управления ActiveX для Flash Player отправить событие FlashCall . Flash Player преобразует имя функции и имеющиеся параметры в строку XML. Контейнер может выполнять доступ к этой информации в свойстве request объекта события и использовать его для определения метода выполнения собственного кода. Чтобы вернуть значение в ActionScript, код контейнера вызывает метод SetReturnValue() объекта ActiveX, передавая результат (последовательно представленный в виде строки XML) в качестве параметра этого метода. Дополнительные сведения о формате XML, использованном для этой связи, см. в разделе « Формат XML внешнего API ».

Независимо от того, является ли контейнер веб-обозревателем или другим контейнером ActiveX, если вызов неудачен или метод контейнера не указывает возвращаемое значение, возвращается null . Метод ExternalInterface.call() выдает исключение SecurityError, если содержащая его среда принадлежит к изолированной программной среде, к которой не имеет доступа вызывающий код. Эту проблему можно обойти, установив соответствующее значение allowScriptAccess в среде, содержащей метод. Например, чтобы изменить значение allowScriptAccess на странице HTML, вам необходимо изменить соответствующий атрибут в тегах object и embed .

Вызов кода ActionScript из контейнера

Контейнер может вызвать только тот код ActionScript, который находится в функции — он не может вызвать никакой другой код ActionScript. Чтобы вызвать функцию ActionScript из приложения контейнера, необходимо сделать две вещи: зарегистрировать функцию в классе ExternalInterface, а затем вызвать ее из кода контейнера.

Во-первых, необходимо зарегистрировать вашу функцию ActionScript, чтобы указать, что она должна быть доступна контейнеру. Воспользуйтесь методом ExternalInterface.addCallback() следующим образом:

function callMe(name:String):String 
{ 
    return "busy signal"; 
} 
ExternalInterface.addCallback("myFunction", callMe);

Метод addCallback() принимает два параметра. Первый из них — это имя функции в виде объекта String. Это имя, под которым функция будет известна в контейнере. Второй параметр — это фактическая функция ActionScript, которая будет выполняться при вызове контейнером определенного имени функции. Поскольку это разные имена, можно указать имя функции, которое будет использоваться в качестве контейнера, даже если фактическая функция ActionScript имеет другое имя. Это особенно полезно, если имя функции неизвестно (например, если указывается анонимная функция или если подлежащая вызову функция определяется во время выполнения).

После регистрации функции ActionScript в классе ExternalInterface контейнер может вызвать эту функцию. Метод вызова зависит от типа контейнера. Например, код JavaScript в веб-обозревателе вызывает функцию ActionScript с помощью зарегистрированного имени функции, как если бы это был метод объекта обозревателя Flash Player (то есть, метод объекта JavaScript, отражающий тег object или embed ). Иными словами, передаются параметры, а результат возвращается так, как если бы вызывалась локальная функция.

<script language="JavaScript"> 
    // callResult gets the value "busy signal" 
    var callResult = flashObject.myFunction("my name"); 
</script> 
... 
<object id="flashObject"...> 
    ... 
    <embed name="flashObject".../> 
</object>

Кроме того, при вызове функции ActionScript в SWF-файле, запущенном в приложении для настольных систем, зарегистрированное имя функции и любые параметры должны быть представлены в виде строки формата XML. Затем вызов выполняется путем обращения к метолу CallFunction() элемента управления ActiveX, где в качестве параметра выступает строка XML. Дополнительные сведения о формате XML, использованном для этой связи, см. в разделе « Формат XML внешнего API ».

В любом случае значение, возвращаемое функцией ActionScript, передается обратно в код контейнера. Передача осуществляется напрямую в виде значения, когда вызывающей стороной является код JavaScript в обозревателе, либо в виде значения в формате XML, когда вызов выполняется контейнером ActiveX.

Формат XML внешнего API

Связь между ActionScript и приложением, в котором находится элемент управления ActiveX для Shockwave Flash, реализуется с помощью формата XML, используемого для кодирования вызовов функции и значений. Существует две части формата XML, использованного внешним API. Один формат применяется для представления вызовов функции. Другой формат применяется для представления отдельных значений. Этот параметр используется для обозначения параметров в функциях, а также значений, возвращаемых функциями. Формат XML для вызовов функций применяется для вызовов кода ActionScript и из самого кода ActionScript. При вызове функции из ActionScript Flash Player передает XML в контейнер. Если вызов осуществляется из контейнера, Flash Player ожидает, что приложение контейнера передаст строку XML в этом формате. В следующем фрагменте XML показан пример вызова функции в формате XML:

<invoke name="functionName" returntype="xml"> 
    <arguments> 
        ... (individual argument values) 
    </arguments> 
</invoke>

Корневой узел носит имя invoke . У него есть два атрибута: name указывает на имя вызываемой функции, а returntype всегда присваивается значение xml . Если вызов функции включает параметры, узел invoke имеет дочерний узел arguments , чьи дочерние узлы являются значениями параметров, имеющими формат отдельных значений, как указано ниже.

Отдельные значения, включая параметры функций и возвращаемые ими значения, используют схему форматирования, которая включает сведения о типе данных помимо фактических значений. В следующей таблице перечислены классы ActionScript. Для кодирования значений с этим типом данных применяется формат XML.

Класс/значение ActionScript

Класс/значение C#

Формат

Комментарии

null

null

<null/>

Boolean true

bool true

<true/>

Boolean false

bool false

<false/>

String

string

<string>строковое значение</string>

Number, int, uint

single, double, int, uint

<number>27.5</number> 
<number>-12</number>

Массив (элементы могут быть смешанных типов)

Коллекция, способная включать элементы смешанных типов (например, ArrayList или object[])

<array> 
    <property id="0"> 
        <number>27.5</number> 
    </property> 
    <property id="1"> 
        <string>Hello there!</string> 
    </property> 
    ... 
</array>

Узел property определяет отдельные элементы, а атрибут id является числовым указателем, начинающимся с нуля.

Object

Словарь со строковыми ключами и значениями объектов (например, HashTable со строковыми ключами)

<object> 
    <property id="name"> 
        <string>John Doe</string> 
    </property> 
    <property id="age"> 
        <string>33</string> 
    </property> 
    ... 
</object>

Узел property определяет отдельные свойства, а атрибут id является именем свойства (строкой).

Другие встроенные или заказные классы

<null/> or  
<object></object>

ActionScript кодирует другие объекты как нулевые или пустые. В любом случае все значения свойств теряются.

Примечание. В качестве примера в этой таблице указаны эквивалентные классы C# помимо классов ActionScript. Однако внешний API можно использовать для связи с любым языком программирования или средой выполнения, которая поддерживает элементы управления ActiveX и не ограничивается приложениями на C#.

При составлении собственных приложений с применением внешнего API и приложения контейнера ActiveX, вы, возможно, сочтете удобным создание прокси-сервера, который осуществит задачу преобразования собственных вызовов функции в последовательный формат XML. Пример класса прокси-сервера, написанного на C#, представлен в разделе Подробно о классе ExternalInterfaceProxy.