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」という名前に紐付けられたメソッドの呼び出しを行なっています。


