Haxe: Flash, JavaScript間 非同期通信サンプル
Flash から JavaScript 内処理を呼び出すには ExternalInterface を利用します。
ここで、JavaScript 側に非同期通信を行う処理(jQuery の ajaxメソッド呼び出し 等)があり、通信処理終了後の通信結果を Flash 側に返却したい場合、どういう処理にすればよいかのサンプルを作成しました。ActionScript, JavaScript どちらも Haxe で記述しています。
Google Play Game Services といった、JavaScript 用 API は用意されているものの、Flash 用 API は用意されていない、そんな場合に今回のような記述を利用します。
サンプル
簡単な処理の流れとしては以下となります。
(1)Flash から JavaScript の処理を呼び出す
(2)JavaScript 側で jQuery の ajax メソッドによるテキストファイル読み込み
(3)JavaScript 側でファイル読み込み完了後 Flash 側のメソッド呼び出し
最後に Flash 側の処理が呼び出されると、swf 領域内に「called!」という表示が行われます。
以下がサンプルとなります。
http://www.dango-itimi.com/blog/swf/197/
サンプルファイル一式は以下の URL からダウンロードできます。セキュリティ関連の設定を行わないとローカル環境上では動作しません。
http://www.dango-itimi.com/blog/swf/197/trunk.zip
サンプルソースコード
サンプルファイル一式内のソースコードを一部抜粋して以下に記述します。
html
swfobject による swf 埋め込みを行なっています。
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja"> <head> …略… <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js" ></script> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js" ></script> <script type="text/javascript" src="main.js"></script> <script language="javascript"> var flashvars = {}; var params = {allowScriptAccess: 'always'}; var attributes = { id: 'external_swf', name: 'external_swf' }; swfobject.embedSWF( 'test.swf', 'swf', '400', '300', '11', "", flashvars, params, attributes ); </script> </head> <body> <div> <div id="swf"></div> </div> </body> </html>
注意点としまして、swfobject による swf 表示ということから embed タグによる swf 埋め込みは行われておらず、昔のブラウザでは動かない可能性があります。
Flash
package sample; import flash.events.Event; import flash.system.Security; import flash.external.ExternalInterface; class FlashSample { private var mainFunction:Void->Void; private var called:Bool; public static function main(){ new FlashSample(); } public function new(){ var stage = flash.Lib.current; stage.addEventListener(Event.ENTER_FRAME, run); ExternalInterface.addCallback("sendToFlash", callFromJavascript); ExternalInterface.call("sample.JavascriptSample.start"); mainFunction = waitToCallFromJavascript; } private function callFromJavascript(){ called = true; } private function run(event:Event){ mainFunction(); } private function waitToCallFromJavascript(){ if(called){ trace("called!"); mainFunction = finish; } } private function finish(){ } }
まず、callFromJavascript というメソッドを用意し、JavaScript の処理終了後に呼び出されるメソッドを用意しておきます。
次に、sample.JavascriptSample.start メソッドを呼び出す事で、JavaScript のテキストファイル読み込み処理が開始されます。
waitToCallFromJavascript メソッドでは、JavaScript から処理完了を示す callFromJavascript メソッド呼び出しが行われるまで待機しています。
JavaScript
package sample; import js.Lib; import js.html.HTMLCollection; import jQuery.JQuery; import js.Browser; @:expose class JavascriptSample { public static function main(){ } public static function start(){ new JavascriptSample(); } private var SWF_NAME = "external_swf"; public function new(){ var element = getSwfElement(); JQuery._static.ajax({ url: "test.dat", type: "GET", success: function(data){ trace("success"); element.sendToFlash(); }, error: function(request, status, errorThrown){ trace("error", request, status, errorThrown); } }); } private function getSwfElement():Dynamic{ var element:Dynamic = (Browser.navigator.appName.indexOf("Microsoft") != -1) ? untyped window[SWF_NAME] : untyped document[SWF_NAME]; return (element.constructor == HTMLCollection) ? element[0] : element; } }
Flash からは start メソッドが呼び出され、JavascriptSample コンストラクタ内では JQuery の ajax メソッドによるテキストファイル読み込み処理を実行しています。読み込み処理完了後は、Flash 内で「sendToFlash」という名前に紐付けられたメソッドの呼び出しを行なっています。