Harici API örneği: Bir web tarayıcısında ActionScript ve JavaScript arasındaki iletişim

Flash Player 9 ve üstü, Adobe AIR 1.0 ve üstü

Bu örnek uygulama, kişinin kendisiyle sohbet etmesine olanak sağlayan bir Anında Mesajlaşma uygulaması bağlamında, bir web tarayıcısında ActionScript ile JavaScript arasında iletişim kurulmasına yönelik uygun teknikleri gösterir. Mesajlar, web sayfasındaki bir HTML formu ile harici API kullanan bir SWF arabirimi arasında gönderilir. Bu örnekle gösterilen teknikler arasında şunlar yer alır:

  • İletişim kurulmadan önce tarayıcının iletişim kurmak için hazır olduğunu doğrulayarak düzgün şekilde iletişimi başlatma

  • Kabın harici API'yi destekleyip desteklemediğini kontrol etme

  • ActionScript'ten JavaScript işlevlerini çağırarak parametreler iletme ve buna yanıt olarak değerler alma

  • ActionScript yöntemlerini JavaScript tarafından çağrılabilir duruma getirme ve bu çağrıları gerçekleştirme

Bu örneğin uygulama dosyalarını edinmek için bkz. www.adobe.com/go/learn_programmingAS3samples_flash_tr. Introvert IM uygulama dosyaları Samples/IntrovertIM_HTML klasöründe bulunabilir. Uygulama aşağıdaki dosyaları içerir:

File

Açıklama

IntrovertIMApp.fla

veya

IntrovertIMApp.mxml

Flash (FLA) veya Flex (MXML) için ana uygulama dosyası.

com/example/programmingas3/introvertIM/IMManager.as

ActionScript ile kap arasında iletişim kuran ve bu iletişimi yöneten sınıf

com/example/programmingas3/introvertIM/IMMessageEvent.as

Kaptan bir mesaj alındığında IMManager sınıfı tarafından gönderilen özel olay türü.

com/example/programmingas3/introvertIM/IMStatus.as

Değerleri, uygulamada seçilebilen farklı "kullanılabilirlik" durum değerlerini temsil eden numaralandırma.

html-flash/IntrovertIMApp.html

veya

html-template/index.template.html

Flash uygulaması için HTML sayfası (html-flash/IntrovertIMApp.html) veya Adobe Flex uygulaması için kap HTML sayfası oluşturmak üzere kullanılan şablon (html-template/index.template.html). Bu dosya, uygulamanın kap parçasını oluşturan tüm JavaScript işlevlerini içerir.

ActionScript tarayıcı iletişimi için hazırlanma

Harici API'nin en yaygın kullanımlarından biri, ActionScript uygulamalarının bir web tarayıcısıyla iletişim kurmasına olanak sağlamaktır. ActionScript yöntemleri harici API'yi kullanarak JavaScript'te yazılmış bir kod çağırabilir ve aksi durumda tam tersi olur. Tarayıcıların ve dahili olarak sayfa oluşturma şekillerinin karmaşık olması nedeniyle, bir SWF belgesinin HTML sayfasındaki birinci JavaScript çalıştırılmadan önce kendi geri çağrılarını kaydedeceğini garanti etmenin bir yolu yoktur. Bu nedenle, JavaScript'ten SWF belgesindeki işlevler çağrılmadan önce, SWF belgenizin, bağlantıları kabul etmeye hazır olduğunu HTML sayfasına bildirmek için her zaman HTML sayfasını çağırması gerekir.

Örneğin, IMManager sınıfı tarafından gerçekleştirilen adımlar dizisiyle, Introvert IM öğesi tarayıcının iletişim için hazır olup olmadığını belirler ve SWF dosyasını iletişim için hazırlar. Birinci adım (tarayıcının iletişim için ne zaman hazır olduğunu belirleme), şu şekilde IMManager yapıcısında gerçekleşir:

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."); 
    } 
}

İlk olarak, kod ExternalInterface.available özelliğini kullanarak geçerli kapta harici API'nin kullanılabilir olup olmadığını kontrol eder. Harici API kullanılabilir durumdaysa, kod, iletişim kurma işlemini başlatır. Harici bir uygulamayla iletişim kurmayı denediğinizde güvenlik istisnaları ve başka hatalar oluşabildiğinden, kod bir try bloğunda sarılır. (Kısa olması için, karşılık gelen catch blokları çıkarılır.)

Daha sonra kod, burada listelenen isContainerReady() yöntemini çağırır:

private function isContainerReady():Boolean 
{ 
    var result:Boolean = ExternalInterface.call("isReady"); 
    return result; 
}

Bunun sonucunda isContainerReady() yöntemi, şu şekilde, isReady() JavaScript işlevini çağırmak için ExternalInterface.call() yöntemini kullanır:

<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>

isReady() işlevi yalnızca jsReady değişkeninin değerini döndürür. Bu değişken başlangıçta false değerindedir; web sayfasının onload olayı tetiklendikten sonra, değişkenin değeri true olarak değiştirilir. Başka bir deyişle, sayfa yüklenmeden önce ActionScript isReady() işlevini çağırırsa, JavaScript ExternalInterface.call("isReady") için false değerini döndürür ve sonra da ActionScript isContainerReady() yöntemi false değerini döndürür. Sayfa yüklendikten sonra, JavaScript isReady() işlevi true değerini döndürür, böylece ActionScript isContainerReady() yöntemi de true değerini döndürür.

IMManager yapıcısına geri döndüğümüzde, kabın hazır olma durumuna bağlı olarak iki şeyden biri gerçekleşir. isContainerReady() öğesi true değerini döndürürse, kod yalnızca setupCallbacks() yöntemini çağırır ve bu da JavaScript ile iletişim kurma işlemini tamamlar. Diğer bir yandan, isContainerReady() öğesi false değerini döndürürse, işlem beklemeye alınır. Aşağıdaki gibi, bir Timer nesnesi oluşturulur ve bu nesneye her 100 milisaniyede bir timerHandler() yöntemini çağırması bildirilir:

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(); 
    } 
}

timerHandler() yöntemi her çağrıldığında, bir kez daha isContainerReady() yönteminin sonucunu kontrol eder. Kap başlatıldıktan sonra, bu yöntem true değerini döndürür. Daha sonra kod, Timer öğesini durdurur ve tarayıcıyla iletişim kurma işlemini bitirmek için setupCallbacks() yöntemini çağırır.

ActionScript yöntemlerini JavaScript kullanımına sunma

Önceki örnekte gösterildiği gibi, kod tarayıcının hazır olduğunu belirledikten sonra setupCallbacks() yöntemi çağrılır. Bu yöntem, burada gösterildiği gibi, JavaScript'ten gelen çağrıları alacak şekilde ActionScript'i hazırlar:

private function setupCallbacks():void 
{ 
    // Register the SWF client functions with the container 
    ExternalInterface.addCallback("newMessage", newMessage); 
    ExternalInterface.addCallback("getStatus", getStatus); 
    // Notify the container that the SWF is ready to be called. 
    ExternalInterface.call("setSWFIsReady"); 
}

setCallBacks() yöntemi, JavaScript'ten çağrılabilir durumda olacak iki yöntemi kaydetmek için ExternalInterface.addCallback() öğesini çağırarak kapla iletişim kurmaya hazırlanma görevini bitirir. Bu kodda, birinci parametre olan yöntemin JavaScript tarafından bilinecek adı("newMessage" ve "getStatus"), yöntemin ActionScript'teki adıyla aynıdır. (Bu durumda, farklı adlar kullanılmasının bir avantajı olmadığından kolaylık sağlamak için aynı ad yeniden kullanılmıştır.) Son olarak, kaba ActionScript işlevlerinin kaydedildiğini bildiren setSWFIsReady() JavaScript işlevini çağırmak için ExternalInterface.call() yöntemi kullanılır.

ActionScript'ten tarayıcıya iletişim

Introvert IM uygulaması, kap sayfasındaki JavaScript işlevlerinin çağrılmasına ilişkin çok çeşitli örnekler gösterir. En basit durumda (setupCallbacks() yöntemindeki bir örnek), herhangi bir parametre iletilmeden veya karşılığında bir değer alınmadan setSWFIsReady() JavaScript işlevi çağrılır:

ExternalInterface.call("setSWFIsReady");

isContainerReady() yönteminin başka bir örneğinde, ActionScript isReady() işlevini çağırır ve karşılığında bir Boolean değeri alır:

var result:Boolean = ExternalInterface.call("isReady");

Ayrıca harici API kullanarak da JavaScript işlevlerine parametreler iletebilirsiniz. Örneğin, kullanıcı "dönüştürme ortağına" yeni bir mesaj gönderdiğinde çağrılan, IMManager sınıfının sendMessage() yöntemini göz önünde bulundurun:

public function sendMessage(message:String):void 
{ 
    ExternalInterface.call("newMessage", message); 
}

Yine belirlenen JavaScript işlevini çağırmak için ExternalInterface.call() öğesi kullanılarak yeni mesaj tarayıcıya bildirilir. Ayrıca, mesajın kendisi de ek bir parametre olarak ExternalInterface.call() öğesine gönderilir ve sonra da parametre olarak newMessage() JavaScript işlevine iletilir.

JavaScript'ten ActionScript kodunu çağırma

İletişimin iki yönlü olduğu varsayılır ve Introvert IM uygulaması da bir istisna değildir. Flash Player IM istemcisi mesaj göndermek için JavaScript'i çağırmakla kalmaz, HTML formu da mesaj göndermek için JavaScript kodunu çağırır ve SWF dosyasından bilgi ister. Örneğin, SWF dosyası iletişim kurmayı bitirdiğini ve iletişim kurmak için hazır olduğunu kaba bildirdiğinde tarayıcının yapacağı ilk şey, SWF IM istemcisinden ilk kullanıcı kullanılabilirliği durumunu almak için IMManager sınıfının getStatus() yöntemini çağırmaktır. Aşağıdaki gibi bu, web sayfasında, updateStatus() işlevinde yapılır:

<script language="JavaScript"> 
... 
function updateStatus() 
{ 
    if (swfReady) 
    { 
        var currentStatus = getSWF("IntrovertIMApp").getStatus(); 
        document.forms["imForm"].status.value = currentStatus; 
    } 
} 
... 
</script>

Kod, SWF dosyasının ExternalInterface sınıfı ile yöntemlerini kaydettiğini tarayıcıya bildirip bildirmediğini izleyen swfReady değişkeninin değerini kontrol eder. SWF dosyası iletişimi almaya hazırsa, sonraki satır (var currentStatus = ...) gerçekten IMManager sınıfında getStatus() yöntemini çağırır. Bu kod satırında üç şey gerçekleşir:

  • getSWF() JavaScript işlevi çağrılarak SWF dosyasını temsil eden bir JavaScript'e başvuru döndürülür. getSWF() öğesine iletilen parametre, bir HTML sayfasında birden çok SWF dosyası olması durumunda hangi tarayıcı nesnesinin döndürüleceğini belirler. Bu parametreye iletilen değerin, SWF dosyasını dahil etmek için kullanılan object etiketinin id niteliğiyle ve embed etiketinin name niteliğiyle eşlemesi gerekir.

  • SWF dosyasına başvuru kullanılarak, getStatus() yöntemi, SWF nesnesinin bir yöntemiymiş gibi çağrılır. Bu durumda, “getStatus” işlev adı, ExternalInterface.addCallback() kullanılarak ActionScript işlevinin kaydedildiği ad olduğundan bu işlev adı kullanılır.

  • getStatus() ActionScript yöntemi bir değer döndürür ve bu değer currentStatus değişkenine atanır, daha sonra da bu değer status metin alanının içeriği (value özelliği) olarak atanır.

Not: Kodu takip ederseniz, updateStatus() işlevinin kaynak kodunda, getSWF() işlevini çağıran kod satırının gerçekte şu şekilde yazıldığını fark edersiniz: var currentStatus = getSWF("${application}").getStatus(); ${application} metni, HTML sayfası şablonunda bir yer tutucudur; Adobe Flex Builder, uygulama için gerçek HTML sayfasını oluşturduğunda, bu yer tutucu metnin yerini, object etiketinin id niteliği olarak ve embed etiketinin name niteliği olarak kullanılan metnin aynısı (örnekte IntrovertIMApp) alır. getSWF() işlevi tarafından beklenen değer budur.

sendMessage() JavaScript işlevi, ActionScript işlevine bir parametre iletilmesini gösterir. (sendMessage(), kullanıcı HTML sayfasında Gönder düğmesine bastığında çağrılan işlevdir.)

<script language="JavaScript"> 
... 
function sendMessage(message) 
{ 
    if (swfReady) 
    { 
        ... 
        getSWF("IntrovertIMApp").newMessage(message); 
    } 
} 
... 
</script>

newMessage() ActionScript yöntemi yalnızca bir parametre bekler, böylece JavaScript message değişkeni, JavaScript kodundaki newMessage() yöntem çağrısında bunu bir parametre olarak kullanarak ActionScript'e iletilir.

Tarayıcı türünü algılama

Tarayıcıların içeriğe erişme şekli farklı olduğundan, bu örnekteki getSWF() JavaScript işlevinde gösterildiği gibi, pencere veya belge nesnesini kullanarak kullanıcının hangi tarayıcıyı çalıştırdığını algılamak ve tarayıcıya özgü sözdizimine göre filme erişmek için her zaman JavaScript kullanılması önemlidir:

<script language="JavaScript"> 
... 
function getSWF(movieName) 
{ 
    if (navigator.appName.indexOf("Microsoft") != -1) 
    { 
        return window[movieName]; 
    } 
    else 
    { 
        return document[movieName]; 
    } 
} 
... 
</script>

Komut dosyanız kullanıcının tarayıcı türünü algılamıyorsa, kullanıcı bir HTML kabındaki SWF dosyalarını oynatırken beklenmeyen davranışlarla karşılaşabilir.