L'API esterna viene molto spesso utilizzata per consentire alle applicazioni ActionScript di comunicare con un browser Web. Grazie all'API esterna, i metodi ActionScript possono chiamare il codice scritto in JavaScript e viceversa. In virtù della complessità dei browser e del modo in cui effettuano il rendering interno delle pagine, non è possibile garantire che un documento SWF registri le proprie funzioni di callback prima che venga eseguito il primo codice JavaScript della pagina HTML. Per tale motivo, prima di chiamare le funzioni nel documento SWF da JavaScript, il documento SWF deve sempre chiamare la pagina HTML per notificarle che il documento SWF è pronto per accettare le connessioni.
Attraverso una serie di operazioni eseguite, ad esempio, dalla classe IMManager, l'applicazione Introvert IM determina se il browser è pronto per la comunicazione e prepara il documento SWF di conseguenza. La prima operazione, ovvero determinare quando il browser è pronto per la comunicazione, si svolge nella funzione di costruzione IMManager, come indicato di seguito:
public function IMManager(initialStatus:IMStatus)
{
_status = initialStatus;
// Check if the container is able to use the external API.
if (ExternalInterface.available)
{
try
{
// This calls the isContainerReady() method, which in turn calls
// the container to see if Flash Player has loaded and the container
// is ready to receive calls from the SWF.
var containerReady:Boolean = isContainerReady();
if (containerReady)
{
// If the container is ready, register the SWF's functions.
setupCallbacks();
}
else
{
// If the container is not ready, set up a Timer to call the
// container at 100ms intervals. Once the container responds that
// it's ready, the timer will be stopped.
var readyTimer:Timer = new Timer(100);
readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
readyTimer.start();
}
}
...
}
else
{
trace("External interface is not available for this container.");
}
}
Innanzitutto, il codice verifica se l'API esterna è almeno disponibile nel contenitore corrente utilizzando la proprietà
ExternalInterface.available
. In caso affermativo, inizia il processo di impostazione della comunicazione. Poiché quando si tenta la comunicazione con un'applicazione esterna possono verificarsi delle eccezioni di sicurezza e altri errori, il codice viene racchiuso in un blocco
try
(i blocchi
catch
corrispondenti sono stati omessi dall'elenco per ragioni di spazio).
Il codice successivo chiama il metodo
isContainerReady()
, rappresentato qui:
private function isContainerReady():Boolean
{
var result:Boolean = ExternalInterface.call("isReady");
return result;
}
Il metodo
isContainerReady()
utilizza a propria volta il metodo
ExternalInterface.call()
per chiamare la funzione JavaScript
isReady()
, come indicato di seguito:
<script language="JavaScript">
<!--
// ------- Private vars -------
var jsReady = false;
...
// ------- functions called by ActionScript -------
// called to check if the page has initialized and JavaScript is available
function isReady()
{
return jsReady;
}
...
// called by the onload event of the <body> tag
function pageInit()
{
// Record that JavaScript is ready to go.
jsReady = true;
}
...
//-->
</script>
La funzione
isReady()
restituisce semplicemente il valore della variabile
jsReady
. Tale variabile inizialmente è
false
; quando l'evento
onload
della pagina Web è stato attivato, il valore della variabile diventa
true
. In altre parole, se ActionScript chiama la funzione
isReady()
prima che la pagina sia stata caricata, JavaScript restituisce
false
a
ExternalInterface.call("isReady")
, e di conseguenza il metodo ActionScript
isContainerReady()
restituisce
false
. Una volta caricata la pagina, la funzione JavaScript
isReady()
restituisce
true
, pertanto anche il metodo ActionScript
isContainerReady()
restituisce
true
.
Tornando alla funzione di costruzione IMManager, a seconda della prontezza del contenitore può verificarsi una delle due condizioni seguenti. Se
isContainerReady()
restituisce
true
, il codice chiama semplicemente il metodo
setupCallbacks()
, che completa il processo di impostazione della comunicazione con JavaScript. Se invece
isContainerReady()
restituisce
false
, il processo viene essenzialmente sospeso. Viene creato un oggetto Timer a cui viene ordinato di chiamare il metodo
timerHandler()
ogni 100 millisecondi, come indicato di seguito:
private function timerHandler(event:TimerEvent):void
{
// Check if the container is now ready.
var isReady:Boolean = isContainerReady();
if (isReady)
{
// If the container has become ready, we don't need to check anymore,
// so stop the timer.
Timer(event.target).stop();
// Set up the ActionScript methods that will be available to be
// called by the container.
setupCallbacks();
}
}
Ogni volta che il metodo
timerHandler()
viene chiamato, verifica ancora una volta il risultato del metodo
isContainerReady()
. Una volta inizializzato il contenitore, tale metodo restituisce il valore
true.
A quel punto, il codice arresta il timer e chiama il metodo
setupCallbacks()
per completare il processo di impostazione della comunicazione con il browser.