ページへ戻る

− Links

 印刷 

AndroidでのANEの作成​/Android側の作成 のバックアップソース(No.10) :: NJF Wiki

xpwiki:AndroidでのANEの作成/Android側の作成 のバックアップソース(No.10)

« Prev[5]  Next »[6]
[[AndroidでのANEの作成]]に戻る。

ANEを作成するためには、Android側のプログラムをまとめたjarファイルが必要となります。その制作方法やテストの仕方をこちらでご紹介します。

*プロジェクトの作成 [#v878cca4]
まずAndroid Studioでテスト用にAndroidで実行するためのプロジェクトを作成します。
Android Studio起動後に「Start a new Android Studio project」を選択します。

&ref(asstart.jpg,mw:480,mh:360);

次にApplication nameを指定します。ここでは「AneAlertSample」としています。ドメイン名はパッケージ名のいつものくせで「jp.njf」としたらひっくり返されました。

&ref(newproject.jpg,mw:480,mh:360);

次のターゲットの設定は「Phone and Tablet」として、Minimum SDKは特に理由が無ければAPI10にしておくと良いでしょう。

&ref(target.jpg,mw:480,mh:360);

次のActivityの追加はどれでも良いのですが、Empty Activityとしておくのが無難です。

&ref(addactivity.jpg,mw:480,mh:360);

次のActivityの名前はなんでも良いので、そのままにしておきます。

&ref(customizeactivity.jpg,mw:480,mh:360);

「Finish」ボタンを押すとプロジェクトが作成されます。

ひとまず、この状態で問題が無いかAndroidにつなげてみて実行して、なにもない画面が表示されるか試してみることをお勧めします。

*テスト用ボタンの設置 [#gf75d92b]
ANEの作成はけっこう面倒です。それを何度もやらなくてすむように、Android上でテストはできるだけ行ってから、ANEの作成にうつった方が効率的です。そのためのテスト用ボタンを設置します。

まず、左側のナビゲーションから「aap/res/layout/activity_main.xml」を選択します。

&ref(activityxml.jpg,mw:480,mh:360);

すると右側にレイアウト編集画面が出るはずですので、Widgetsの下のボタンをドラッグ&ドロップして好きな場所にボタンを設置します。

&ref(newbutton.jpg,mw:480,mh:360);

このボタンをクリックして選択状態にすると右側のpropertyが表示されるので、そのうちの「id」を「showAlertButton」に、「text」を「Show Alert」とします。

&ref(property.jpg,mw:480,mh:360);

さらに画面上の「Hello World」のテキストは使わないので選択した上でデリートボタンを押して消します。

すると以下のような画面になります。

&ref(screen.jpg,mw:480,mh:360);

これでボタンの設置は終了です。実行してみると押してもなにも起こらないボタンが表示されるはずです。

*ANE用のライブラリの作成 [#pbc67169]

作成したボタンを押すとアラート画面が表示されるようにします。
このままjavaフォルダ以下に処理を書いても良いのですが、そうするとActivityなどのテスト用に作ったものまでjarファイルに含まれてしまいます。
万が一にもテスト用のコードが動いてしまうようなことがないように、ここではAcitivityを含まないライブラリを別に作成します。
テスト用のコードがANEに入ったままでも通常は害がなく、ライブラリを作成せずにANEをつくることも可能ですので、面倒な人はそのままjavaフォルダ以下にANEの処理をするクラスを作成しても良いでしょう。ただし、ライブラリの作成は簡単なのでさほど手間が省けるわけではありませんし、整理のためにも別ライブラリにしておいた方が便利です。

Android StudioでFile->New->New Moduleを選択します。

&ref(newmodule.jpg,mw:480,mh:360);

次に「Android Library」を選択します。

&ref(newmoduleandroidlibrary.jpg,mw:480,mh:360);

次のライブラリ名は「ANEAlert」としておきます。

&ref(androidLibraryName.jpg,mw:480,mh:360);

「Finish」ボタンを押すとライブラリが作成されます。

&ref(newlibrarynavigator.jpg,mw:480,mh:360);

*主処理の追加とAndroidアプリとしてのテスト [#n6d6c2ec]
先ほど追加したライブラリに処理を書いて行きます。まず、anealert/java以下に「njf.jp.anealert.ANEAlert」クラスを加えます。

&ref(anemainclass.jpg,mw:480,mh:360);(クリックで拡大)

もし自分のと表示がちょっと違うという場合はプロジェクトタブの上のバーの右側、「<>」という部分をクリックして「Android」を選択してください。

&ref(navichange.jpg,mw:480,mh:360);

ANE本体となる「njf.jp.anealert.ANEAlert」クラスの中は以下の通りです。

 package njf.jp.anealert;

 import android.app.Activity;
 import android.app.AlertDialog;

 public class ANEAlert {
     private Activity activity;
     private AlertDialog alertDialog;
     public ANEAlert(Activity activity){
         this.activity = activity;
     }
     public void showAlert(String title,String message){
         if(alertDialog == null){
             alertDialog = new AlertDialog.Builder(activity).setTitle(title).setMessage(message).setPositiveButton("OK", null).show();
         }else{
             alertDialog.setTitle(title);
             alertDialog.setMessage(message);
             alertDialog.show();
         }

     }

 }

単にshowメソッドでalertダイアログを表示するだけです。
このクラスを作成したら、appモジュールから呼び出せるようにするため、app内のbuild.gradleの中のdependenciesの所に次の1行を加えます。

 compile project(':anealert')

これを加えたらgradleの同期を行うかどうかの表示がエディタの上に出るので、「Sync Now」をクリックして同期します。

&ref(syncNow.jpg,mw:480,mh:360);

すると、appの下のjavaクラスからもanealertのクラスが参照可能になり、エディターで補完もきくようになります。

次にこれをテスト用に実行するためのMainActivityクラスは以下の通りです。

 package njf.jp.anealertsample;

 import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
 import android.view.View;
 import android.widget.Button;

 import njf.jp.anealert.ANEAlert;

 public class MainActivity extends AppCompatActivity {
     private ANEAlert aneAlert;
     private int alertCounter = 0;
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
         setContentView(R.layout.activity_main);

         aneAlert = new ANEAlert(this);
         Button button = (Button) findViewById(R.id.showAlertButton);
         assert button != null;
         button.setOnClickListener(new View.OnClickListener() {
                                       @Override
                                       public void onClick(View v) {
                                           alertCounter++;
                                           aneAlert.showAlert("Android",alertCounter + " times!");
                                       }

                                   }
         );

     }
 }
これで実行すると、表示するたびに数字が変わるAlertダイアログが表示されます。

&ref(androidss.jpg,mw:480,mh:360);

このように、ANEの作成では一度テスト用のActivityを作ってAndroidアプリとして実行してみるのがお勧めです。
そうではなく、いきなりANEとして作成してAirで動かそうとするとエラーが起きたときにデバッグがとても大変です。
また、その時にはここで紹介したように、ANEの処理はライブラリとして作成しておくと、appの方を好きに書き換えてもANEの方には影響しないので、安全にテストすることが出来ます。

Eclipseで開発していた頃は、ライブラリプロジェクトという、ライブラリのみのプロジェクトが作成できたので、それを使ってANEを作成していました。しかし、Android Studioではライブラリのみのプロジェクトは作成できないようなので、このように何かアプリのプロジェクトを作成してそのなかにライブラリをつくるという手順となります。

*ANE呼び出し処理の追加 [#a17e7947]

いよいよANEの呼び出し部分を作成します。この部分でエラーが起こるとソースを変更するたびにいちいちANE作り替えなければならずデバッグが面倒なので、できるだけシンプルにするように心がけてください。

まず、FlashRuntimeExtensions.jarをadobe airのSDKの中の「lib/android」の下から見つけておきます。次にAndroid Studioの左のナビゲーションのタブを「Project」に切り替えlibsの下にさきほどの「FlashRuntimeExtensions.jar」をここにコピー&ペーストします。

&ref(スクリーンショット 2016-06-26 0.23.36.png,mw:480,mh:360);

この「FlashRuntimeExtensions.jar」をAndroid Studio上で右クリックして、「Add as Library」を選びます。

&ref(addaslib.jpg,mw:480,mh:360);

どのモジュールに加えるかを訪ねられるので「anealert」に加えます。

&ref(createlib.jpg,mw:480,mh:360);

うまくいっていればanealertのbuild.gradleのdependenciesに次の1行が加わっているはずです。

 compile files('libs/FlashRuntimeExtensions.jar')

これでANE呼び出しに必要なAPIが使えるようになりました。

ここで一度ANEからJavaのソースが呼び出される過程を整理しておきます。

+actionscriptでExtensionContext.createExtensionContextメソッドをIDと初期化変数を引数として呼び出す。
+Java側ではIDに対応するFREExtensionが初期化される。このとき初期化変数も渡される。
+actionscriptでExtensionContextのcallメソッドを関数のIDとともに呼び出す。
+Java側ではその関数のIDに対応するFREFunctionクラスのcallメソッドが呼び出される。

となります。

つまりANE呼び出しには二つのクラスが必要です。一つは初期化を行う「FREExtension」を継承したクラスと、もう一つは実際に処理を定義する「FREFunction」を継承したクラスです。

ではまず、FREExtensionを継承したAneHelloWorldFREExtensionクラスは以下のようになります。

 package njf.jp.anealert;

 import com.adobe.fre.FREContext;
 import com.adobe.fre.FREExtension;
 import com.adobe.fre.FREFunction;
 import java.util.HashMap;
 import java.util.Map;

 public class ANEAlertFREExtension implements FREExtension {
     @Override
     public FREContext createContext(String s) {
         FREContext context = new FREContext() {
             @Override
             public Map<String, FREFunction> getFunctions() {
                 Map<String, FREFunction> result = new HashMap<String, FREFunction>();
                 result.put("alert", new ANEAlertFREFunction());
                 return result;
             }

             @Override
             public void dispose() {

             }
         };
         return context;
     }

     @Override
     public void dispose() { }

     @Override
     public void initialize() { }
 }


ここで重要なのはresultというHashMapに"alert"という文字列と、次に定義するANEAlertFREFunctionクラスを設定しているところです。このHashMapをFREContextという、ANEのデータを管理するクラスに設定して返してやることで、"alert"という関数IDによってANEAlertFREFunctionクラスのcallメソッドが呼び出されるようになります。

では最後に実際に呼び出されるクラス、FREFunctionを継承したANEAlertFREFunctionを定義します。

 package njf.jp.anealert;

 import android.app.Activity;
 import android.util.Log;
 import com.adobe.fre.FREContext;
 import com.adobe.fre.FREFunction;
 import com.adobe.fre.FREObject;

 public class ANEAlertFREFunction implements FREFunction {
     private ANEAlert aneAlert;

     @Override
     public FREObject call(FREContext freContext, FREObject[] freObjects) {
         String title = "TITLE";
         String message = "MESSAGE";
         try {
              title = freObjects[0].getAsString();
         } catch (Exception e) {
             Log.e("njf.jp.anealert", "FunctionAdFunction:cant parse arg 1");
         }
         try {
             title = freObjects[1].getAsString();
         } catch (Exception e) {
             Log.e("njf.jp.anealert", "FunctionAdFunction:cant parse arg 2");
         }
         if(aneAlert == null){
             aneAlert = new ANEAlert(freContext.getActivity());
         }
         aneAlert.showAlert(title,message);
         return null;
     }
 }

ここでcallメソッドが実際に呼び出されるメソッド、その引数であるFREContextにはアクテビティの情報など、FREObjectには呼び出しの時の引数が入っています。

*jarファイルの取り出し [#veeed4bc]
(この記事は「[[How to build ANE in Android Studio:http://www.myflashlabs.com/build-ane-android-studio/]] 」を参考にしています)

ここまでくるとANEに必要なjarファイルを作成するのは簡単です。

まず、ツールバーの「Build->Rebuild Project」を選択し、ビルドし直します。そして左のナビゲーションの上の「Project」を選択し(なければ右側のボタンを押す)、「anealert/build/outputs/aar/anealert-release.aar」を探します。

&ref(aar.jpg,mw:480,mh:360);

この「anealert-release.aar」が必要なファイルなので、右クリックして「Reveal in Finder」として表示させるなり、「Copy Path」でパスを確かめるなりして、どこか作業用のフォルダにコピーしてください。

aarファイルは実際にはただのzipファイルなので、この「anealert-release.aar」適当なツールで解凍してください。macなどでは以下のコマンドで行えます。

 unzip anealert-release.aar

するとその中に「classes.jar」というファイルがあるはずです。それがANE作成に必要なjarファイルです。実際、jarファイルの中を見るコマンド

 jar tf classes.jar

を実行してみると、

 njf/jp/anealert/ANEAlert.class
 njf/jp/anealert/ANEAlertFREExtension.class
 njf/jp/anealert/ANEAlertFREFunction.class
 ...
などが表示され、先ほど制作したクラスが全て入っているはずです。一方不要な「MainActivity」クラスは含まれていません。

-[[AndroidでのANEの作成]]に戻る
-[[AndroidでのANEの作成/swcの作成]]に進む


« Prev[5]  Next »[6]