AIR for Androidでネイティブ拡張を試しました その1

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

AIR for Androidでネイティブ拡張を試したので手順をまとめます。
開発環境はFlash Builder 4.6とFlex SDK4.6です。

①Javaプロジェクトを作成
Androidネイティブの処理のプロジェクトです。

②ライブラリをビルドパスに追加
・FlashRuntimeExtensions.jar
[Flex SDKのパス]\lib\android
にあるFlashRuntimeExtensions.jarをビルドパスに追加します。

③ネイティブ(Android)の実装
最初にFREExtensionを実装したクラスを作成し、AIRから呼び出されるファンクションの定義をします。
sayHelloというファンクションを定義しています。

package sample.ane;

import java.util.HashMap;
import java.util.Map;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREExtension;
import com.adobe.fre.FREFunction;

public class SampleFREExtension implements FREExtension {

	@Override
	public FREContext createContext(String arg0) {
		FREContext context = new FREContext() {
			@Override
			public Map<String, FREFunction> getFunctions() {
				Map<String, FREFunction> result = new HashMap<String, FREFunction>();
				result.put("sayHello", new MyFREFunction()); 
				return result;
			}

			@Override
			public void dispose() {}
		};
		
		return context;
	}
	
	@Override
	public void dispose() {}

	@Override
	public void initialize() {}

}


次にFREFunctionを実装したクラスを作成します。
callメソッドをオーバーライドして、ネイティブで行いたい処理を実行します。
今回は"Hello World."という文字列を返すだけです。

package sample.ane;

import com.adobe.fre.FREContext;
import com.adobe.fre.FREFunction;
import com.adobe.fre.FREObject;
import com.adobe.fre.FREWrongThreadException;

public class MyFREFunction implements FREFunction {
	
	@Override
	public FREObject call(FREContext arg0, FREObject[] arg1) {
		try {	
			return FREObject.newObject("Hello World.");
			
		} catch (Exception e) {
			try {
				return FREObject.newObject(e.toString());
			} catch (FREWrongThreadException e1) {}
		}
		
		return null;
	}

}


④jarファイルを作成
プロジェクトをjar形式でエクスポートします。

⑤Flexライブラリプロジェクトを作成
javaで定義したネイティブ機能を呼び出すライブラリのプロジェクトです。
作成する時にモバイルライブラリを選択します。

AIR 3.1の場合は追加コンパイラ引数に
-swf-version 13
を追加します。


これを入れないとコマンドラインでadtコマンドを実行した時に
Invalid swc file. The extension NameSpace requires the SWF verison to be 13 or lower.
というエラーになりました。

⑥ネイティブ拡張の実装
ExtensionContextのcreateExtensionContextの第1引数は⑦で定義するエクステンションIDを指定しています。

package sample.ane
{
	import flash.external.ExtensionContext;
	
	public class SampleExtension
	{
		private var context:ExtensionContext;
		
		public function SampleExtension() {
			context = ExtensionContext.createExtensionContext(
				"sample", "type");
		}
		
		public function sayHello():String {
			return context.call("sayHello") as String;
		}
		
		public function dispose() : void {
			return context.dispose();
		}
	}
}

⑦ネイティブ拡張記述ファイルの作成
⑤で作ったプロジェクトフォルダの直下にextension.xmlという名前で置いています。
nativeLibraryには④で作成したjarファイルを指定します。
initializerとfinalizerには③で作成したクラスを指定します。

<extension xmlns="http://ns.adobe.com/air/extension/2.5">
	<id>sample</id>
	<versionNumber>1.0.0</versionNumber>
		<platforms>
				<platform name="Android-ARM">
						<applicationDeployment>
								<nativeLibrary>sample.jar</nativeLibrary>
								<initializer>sample.ane.SampleFREExtension</initializer>
								<finalizer>sample.ane.SampleFREExtension</finalizer>
						</applicationDeployment>
				</platform>
		</platforms>
</extension>

⑧library.swfの作成
⑥実装したソースをコンパイルしたswcの拡張子をzipにして解凍すると中にあると思うのでそれを
⑤で作ったプロジェクトフォルダの直下に配置します。
以下のようなフォルダ構成になりました。

⑨コマンドラインでANEファイルを作成
コマンドプロンプトを開いてプロジェクトフォルダまで移動してから以下のコマンドを実行します。
adtはFlex SDKのbinフォルダにあるので環境変数Pathに設定しておく必要があります。

adt 
	-package -target ane [aneファイル名] [ネイティブ拡張記述ファイル名]
	-swc bin\[swcファイル名] 
	-platform Android-ARM library.swf [jarファイル名]


今回は署名は省いていますが必要であれば以下のオプションを追加します。
-storetype pkcs12 -keystore [証明書]


⑩Flexモバイルプロジェクトを作成
ネイティブ拡張を使ったサンプルのプロジェクトです。

⑪ビルドパスにANEファイルを設定
⑨で作成したANEファイルを設定します。

⑫ネイティブ拡張を使ったサンプルソースを実装
ボタンを押すとTextAreaにを"Hello World."と表示するサンプルのソースです。

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
				 xmlns:s="library://ns.adobe.com/flex/spark" applicationDPI="160">
	<fx:Script>
		<![CDATA[
			import sample.ane.SampleExtension;
			
			protected function button1_clickHandler(event:MouseEvent):void
			{
				var extension:SampleExtension = new SampleExtension();
				lbl.text = extension.sayHello();
			}
		]]>
	</fx:Script>
	
	<s:VGroup width="100%" height="100%">
		<s:Button label="Click" click="button1_clickHandler(event)"/>
		<s:TextArea id="lbl" width="100%" height="100%"/>
	</s:VGroup>
</s:Application>

⑫実機を使ってデバック、起動
AIRシミュレーターでは実行できないので実機で試しました。