Uso da classe ExternalInterface

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

A comunicação entre o ActionScript e o aplicativo de contêiner pode ser realizada de duas formas: o ActionScript pode chamar o código (como uma função do JavaScript) definido no contêiner ou o código do contêiner pode chamar uma função do ActionScript que foi designada como chamável. De qualquer modo, as informações podem ser enviadas para o código que está sendo chamado e os resultados podem ser retornados para o código que está fazendo a chamada.

Para facilitar essa comunicação, a classe ExternalInterface inclui duas propriedades estáticas e dois métodos estáticos. Esses métodos e propriedades são usados para obter informações sobre a conexão da interface externa, para executar o código no contêiner do ActionScript e para disponibilizar as funções do ActionScript para serem chamadas pelo contêiner.

Obtenção de informações sobre o contêiner externo

A propriedade ExternalInterface.available indica se o Flash Player atual está em um contêiner que oferece uma interface externa. Se a interface externa estiver disponível, esta propriedade será true ; caso contrário, ela será false . Antes de usar qualquer outra funcionalidade na classe ExternalInterface, sempre verifique se o contêiner atual oferece suporte à comunicação da interface externa do seguinte modo:

if (ExternalInterface.available) 
{ 
    // Perform ExternalInterface method calls here. 
}
Nota: A propriedade ExternalInterface.available informa se o contêiner atual é um tipo compatível com a conectividade de ExternalInterface. Ela não informa se o JavaScript está ativado no navegador atual.

A propriedade ExternalInterface.objectID permite determinar o identificador exclusivo da ocorrência do Flash Player (especificamente, o atributo id da tag object no Internet Explorer ou o atributo name da tag embed nos navegadores que usam a interface NPRuntime). Essa ID exclusiva representa o documenta SWF atual no navegador e pode ser usada para fazer referência ao documento SWF (por exemplo, ao chamar uma função do JavaScript em uma página HTML de contêiner). Quando o contêiner do Flash Player não é um navegador da Web, essa propriedade é null .

Chamada do código externo a partir do ActionScript

O método ExternalInterface.call() executa o código no aplicativo de contêiner. Ele requer pelo menos um parâmetro, uma string que contém o nome da função a ser chamada no aplicativo de contêiner. Quaisquer parâmetros adicionais transmitidos para o método ExternalInterface.call() são transmitidos ao longo do contêiner como parâmetros da chamada de função.

// 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);

Se o contêiner for uma página HTML, esse método invocará a função do JavaScript com o nome especificado, que deve ser definido em um elemento script na página HTML de contêiner. O valor de retorno da função do JavaScript é transmitido novamente para o ActionScript.

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

Se o contêiner for algum outro contêiner ActiveX, esse método fará com que o controle ActiveX do Flash Player envie o evento FlashCall . O nome da função e os parâmetros especificados são serializados em uma string XML pelo Flash Player. O contêiner pode acessar essas informações na propriedade request do objeto de evento e usá-las para determinar como seu próprio código deve ser executado. Para retornar um valor para o ActionScript, o código do contêiner chama o método SetReturnValue() do objeto ActiveX, transmitindo o resultado (serializado em uma string XML) como um parâmetro desse método. Para obter mais informações sobre o formato XML usado para essa comunicação, consulte O formato XML da API externa .

Independentemente de o contêiner ser um navegador da Web ou outro contêiner ActiveX, se a chamada falhar ou o método do contêiner não especificar um valor de retorno, null será retornado. O método ExternalInterface.call() lançará uma exceção SecurityError se o ambiente incluído pertencer a uma caixa de proteção de segurança para a qual o código de chamada não tem acesso. Para solucionar isso temporariamente, defina um valor apropriado para allowScriptAccess no ambiente incluído. Por exemplo, para alterar o valor de allowScriptAccess em uma página HTML, edite o atributo adequado nas tags object e embed .

Chamada do código do ActionScript a partir do contêiner

Um contêiner só pode chamar o código do ActionScript que esteja em uma função - nenhum outro código do ActionScript pode ser chamado por um contêiner. Para chamar um função do ActionScript a partir do aplicativo de contêiner, você deve fazer duas coisas: registrar a função com a classe ExternalInterface e chamá-la a partir do código do contêiner.

Primeiro, você deve registrar a função do ActionScript para indicar se ela deve ser disponibilizada para o contêiner. Use o método ExternalInterface.addCallback() do seguinte modo:

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

O método addCallback() tem dois parâmetros. O primeiro, um nome de função como String, é o nome pelo qual a função será reconhecida pelo contêiner. O segundo parâmetro é a função real do ActionScript que será executada quando o contêiner chamar o nome de função definido. Como esses nomes são diferentes, você pode especificar um nome de função que será usado pelo contêiner, mesmo se a função real do ActionScript tiver um nome diferente. Isso é especialmente útil se o nome da função não for conhecido - por exemplo, se uma função anônima for especificada ou se a função a ser chamada for determinada em tempo de execução.

Depois que uma função do ActionScript é registrada com a classe ExternalInterface, o contêiner pode realmente chamar a função. O modo como isso é feito varia de acordo com o tipo de contêiner. Por exemplo, no código do JavaScript em um navegador da Web, a função do ActionScript é chamada com o nome de função registrado, visto que este é um método do objeto de navegador do Flash Player (isto é, um método do objeto JavaScript que representa a tag object ou embed ). Em outras palavras, os parâmetros são transmitidos e um resultado é retornado como uma função local que está sendo chamada.

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

Como alternativa, ao chamar uma função do ActionScript em um arquivo SWF em execução em um aplicativo de área de trabalho, o nome de função registrado e os parâmetros devem ser serializados em uma string XML. Em seguida, a chamada é realmente feita para o método CallFunction() do controle ActiveX com a string XML como parâmetro. Para obter mais informações sobre o formato XML usado para essa comunicação, consulte O formato XML da API externa .

De qualquer modo, o valor de retorno da função do ActionScript é transmitido novamente para o código do contêiner, diretamente como um valor quando o chamador é o código JavaScript em um navegador ou serializado com uma string XML quando o chamador é um contêiner ActiveX.

O formato XML da API externa

A comunicação entre o ActionScript e um aplicativo que hospeda o controle ActiveX do Shockwave Flash usa um formato XML específico para codificar chamadas e valores de função. Duas partes do formato XML são usadas pela API externa. Um formato é usado para representar chamadas de função. Outro formato é usado para representar valores individuais; esse formato é usado para parâmetros em funções e em valores de retorno de função. O formato XML das chamadas de função é usado para chamadas feitas e recebidas pelo ActionScript. Para uma chamada de função a partir do ActionScript, o Flash Player transmite o XML para o contêiner; para uma chamada a partir do contêiner, o Flash Player espera que o aplicativo de contêiner o transmita como uma string XML nesse formato. O fragmento XML a seguir mostra o exemplo de uma chamada de função em formato XML:

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

O nó raiz é o nó invoke . Ele tem dois atributos: name indica o nome da função a ser chamada e returntype é sempre xml . Se a chamada de função incluir parâmetros, o nó invoke terá um nó filho arguments , cujos nós filho serão os valores de parâmetro formatados que usam o formato de valor individual explicado a seguir.

Os valores individuais, incluindo parâmetros de função e valores de retorno de função, usam um esquema de formatação que inclui informações sobre o tipo de dados além dos valores reais. A tabela a seguir lista as classes do ActionScript e o formato XML usado para codificar valores desse tipo de dados:

Classe/valor do ActionScript

Classe/valor do C#

Formato

Comentários

null

null

<null/>

Booliano true

bool true

<true/>

Booliano false

bool false

<false/>

String

string

<string>valor da string</string>

Número, int, uint

único, duplo, int, uint

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

Array (os elementos podem ser de tipos diferentes)

Uma coleção que permite elementos de tipos diferentes, como ArrayList ou object[]

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

O nó property define elementos individuais e o atributo id é o índice numérico baseado em zero.

Objeto

Um dicionário com chaves de string e valores de objeto, como HashTable com chaves de string

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

O nó property define propriedades individuais e o atributo id é o nome da propriedade (uma string).

Outras classes internas ou personalizadas

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

O ActionScript codifica outros objetos como nulos ou como um objeto vazio. De qualquer modo, os valores de propriedade são perdidos.

Nota: Por exemplo, esta tabela mostra as classes C# equivalentes além das classes do ActionScript; no entanto, a API externa pode ser usada para comunicação com qualquer linguagem de programação ou tempo de execução compatível com os controles ActiveX, não se limitando aos aplicativos C#.

Quando está criando seus próprios aplicativos usando a API externa com um aplicativo de contêiner ActiveX, você provavelmente achará útil gravar um proxy que irá converter as chamadas de função nativas no formato XML serializado. Para obter um exemplo de uma classe de proxy gravada em C#, consulte Dentro da classe ExternalInterfaceProxy.