AIR for AndroidでNative Extensionsを試してみた(概要編)の続きです。
前回は、AIR for AndroidでNative拡張する際の開発手順などについて記載しました。
- Androidプロジェクトの作成
- Flexライブラリプロジェクトの作成
- Flexモバイルプロジェクトの作成
今回は、実際にAndroidのNative機能を呼び出すAndroidプロジェクトを作成してみたいと思います。このプロジェクトでは、簡単に実装できて、Native拡張していることが簡単に確認できるよう、Toastクラスを利用したいと思います。
まず、Eclipse(Flash Builder)の「ファイル」メニューから、「Android Project」を新規作成します。
※ Eclipse Android Plug-inが必要です。
プロジェクト名を入力して、「次へ」ボタンをクリックします。
次に、ターゲットとするAndroidのバージョンを選択します。
AIRのAndroidアプリは、Android 2.2から対応していますので、ここでは、「Android 2.2」を選択しています。
続いて、パッケージ名を入力します。
パッケージ名は、ユニークな名称になるよう、所有しているドメイン名などを使用することが多いと思います。ここでは自社のドメイン名を使用していますが、パッケージ名にハイフンは使用できません(ドメイン名はlive-cast.asia)。その代わりにアンダースコアなどを用います。そうすると、パッケージ名は「asia.live_cast.ane」になるのですが、あえて「asia.livecast.ane」にしています。自分が所有していない(所有者がいる可能性がある)ドメイン名を使用しているので、あまりよろしくありませんが、このようにしているのは理由があります。
これについては、後日、触れたいと思います。
「Android Project」が作成されました。
プロジェクトのプロパティより、ビルドバスに、「FlashRuntimeExtensions.jar」を設定します。
FlashRuntimeExtensions.jarは、「Flex SDK 4.6.0」に含まれます。<SDKインストールルート>/lib/android/に保存されています。
続いて、Eclipse(Flash Builder)の「ファイル」メニューから「クラス」を新規作成します。その際には、FlashRuntimeExtensions.jarに含まれる、FREExtensionインターフェイスを実装したクラスにしなければいけません。クラス名はToastExtensionとしました。
作成直後のクラスは以下のようになります。
package asia.livecast.ane; import com.adobe.fre.FREContext; import com.adobe.fre.FREExtension; public class ToastExtension implements FREExtension { @Override public FREContext createContext(String arg0) { // TODO Auto-generated method stub return null; } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void initialize() { // TODO Auto-generated method stub } }
createContextメソッド内(10、11行目)を、以下のコードに書き換えます。
FREContext context = new FREContext() { @Override public void dispose() { // TODO Auto-generated method stub } @Override public Map<String, FREFunction> getFunctions() { // TODO Auto-generated method stub return null; } }; return context;
さらに、getFunctionsメソッド内(11、12行目)を、以下のコードに書き換えます。
HashMap<String, FREFunction> result = new HashMap<String, FREFunction>(); result.put("showLongToast", new FREFunction() { @Override public FREObject call(FREContext arg0, FREObject[] arg1) { // TODO Auto-generated method stub return null; } }); return result;
2行目のputメソッドの第一引数に指定している文字列が、AIR側から呼び出す際の処理の名称になります。第二引数には、関数オブジェクトを指定しており、実行したいAndroidのNative機能はここに実装していくことになります。
この部分は、FREFunctionインターフェイスを実装した別クラスとして定義することもできます。今回は、ShowLongToastFunctionという別クラスとして実装しました。
package asia.livecast.ane; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREObject; public class ShowLongToastFunction implements FREFunction { @Override public FREObject call(FREContext arg0, FREObject[] arg1) { // TODO Auto-generated method stub return null; } }
callメソッド内(11、12行目)を、以下のコードに書き換えます。
String message = ""; if (params.length > 0) { try { message = params[0].getAsString(); } catch (IllegalStateException e) { message = e.getMessage(); } catch (FRETypeMismatchException e) { message = e.getMessage(); } catch (FREInvalidObjectException e) { message = e.getMessage(); } catch (FREWrongThreadException e) { message = e.getMessage(); } } if (!message.equals("")) { Toast.makeText(context.getActivity(), message, Toast.LENGTH_LONG).show(); } return null;
ここでは、パラメータで受けた文字列をToastで表示する処理を実装しています。また、例外が発生した際には、そのエラー内容を表示するようにしています。
ShowLongToastFunctionクラスの全体像は以下のようになりました。
package asia.livecast.ane; import android.widget.Toast; import com.adobe.fre.FREContext; import com.adobe.fre.FREFunction; import com.adobe.fre.FREInvalidObjectException; import com.adobe.fre.FREObject; import com.adobe.fre.FRETypeMismatchException; import com.adobe.fre.FREWrongThreadException; public class ShowLongToastFunction implements FREFunction { @Override public FREObject call(FREContext context, FREObject[] params) { String message = ""; if (params.length > 0) { try { message = params[0].getAsString(); } catch (IllegalStateException e) { message = e.getMessage(); } catch (FRETypeMismatchException e) { message = e.getMessage(); } catch (FREInvalidObjectException e) { message = e.getMessage(); } catch (FREWrongThreadException e) { message = e.getMessage(); } } if (!message.equals("")) { Toast.makeText(context.getActivity(), message, Toast.LENGTH_LONG).show(); } return null; } }
ということで、別クラスにしたShowLongToastFunctionクラスが完成したので、ToastExtensionクラスの関数オブジェクトをインラインで記述している部分を置き換えると、以下のようになります。
HashMap<String, FREFunction> result = new HashMap<String, FREFunction>(); result.put("showLongToast", new ShowLongToastFunction()); return result;
インラインで書くよりもすっきりした感じがします。
※ 好みにもよりますが…
ToastExtensionクラスの全体像は以下のようになります。
package asia.livecast.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 ToastExtension implements FREExtension { @Override public FREContext createContext(String arg0) { FREContext context = new FREContext() { @Override public void dispose() { // TODO Auto-generated method stub } @Override public Map<String, FREFunction> getFunctions() { HashMap<String, FREFunction> result = new HashMap<String, FREFunction>(); result.put("showLongToast", new ShowLongToastFunction()); return result; } }; return context; } @Override public void dispose() { // TODO Auto-generated method stub } @Override public void initialize() { // TODO Auto-generated method stub } }
以上で、AndroidのToastクラスを使ったAndroid Projectの作成は完了です。
他のAndroidのNative機能を使いたい場合にも、同様の手順で作成していくことになります。FREFunctionインターフェイスを実装したクラス(ここではShowLongToastFunctionクラス)内の処理を変えていけば良いわけですが、AndroidのNative側の処理を記述する際には、Androidについての知識がある程度必要です。
なかなか長い道のりですね…
次回は、Flexライブラリプロジェクトの作成とaneファイルのパッケージングについてまとめたいと思います。