最初のAndroid NDKアプリケーションではネイティブアプリケーションを作ってそれのデバッグを実施しましたが、今度は通常のAndroid NDKアプリケーションを作成します。
基本的にはAndroid SDKのアプリケーションを作成した後に、追加でネイティブライブラリを作成して二つを合わせてビルドする様な手順となります。まずはAndroid SDKのプロジェクトをeclipseで作成します。最初のAndroidアプリケーションで説明したこととほとんど変わりませんが、注意事項としてApplication.mkでそのディレクトリを指定する必要があるということです。Application.mkでディレクトリを指定するのは手間ですので、この例ではApplication.mkを置いた配下のディレクトリにprojectディレクトリを作成してそこにプロジェクトを配置します。
ネイティブライブラリ作成のためのプロジェクトについては最初のAndroid NDKアプリケーションで説明した通りですので、ここでは特に説明しません。
基本的にAndroidでのネイティブ実行コードへのアクセスは通常のJNIと変わりません。つまり、以下のような手順で行われます。
次にそれぞれの手順を見ていきます。
以下の様にstatic nativeで関数(testMethod)を宣言します。
public class SecondNDKApplication extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.loadLibrary("SecondNDKApplication");
final String result = testMethod();
Log.e("SecondNDKApplication", result);
}
private static native String testMethod();
}
JDKにjavahというJNI向けのツールがあります。使い方としてはjavah -classpath クラスパス -d 出力ディレクトリ 対象クラス(完全修飾で)でヘッダが出力されます。以下が今回出力されたヘッダです。
/* DO NOT EDIT THIS FILE - it is machine generated */ #include/* Header for class com_suddenAngerSystem_SecondNDKApplication */ #ifndef _Included_com_suddenAngerSystem_SecondNDKApplication #define _Included_com_suddenAngerSystem_SecondNDKApplication #ifdef __cplusplus extern "C" { #endif /* * Class: com_suddenAngerSystem_SecondNDKApplication * Method: testMethod * Signature: ()Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_com_suddenAngerSystem_SecondNDKApplication_testMethod (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
この二つは最初のAndroid NDKアプリケーションで説明した通りですので、特に説明しません。
既にソースは記載してしまいましたが、以下の様にloadLibraryでライブラリをロードして、その後ネイティブ関数を起動する。注意点としてはloadLibraryはネイティブ関数起動する前に一度だけ起動する必要があると言うことと、特定の位置にあるライブラリしかロードできないということになります。Android NDKの場合は一つのapkにまとめるため、後者を気にする必要はありませんが、前者についてはstaticイニシャライザで実施するなど考慮が必要です。
public class SecondNDKApplication extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
System.loadLibrary("SecondNDKApplication");
final String result = testMethod();
Log.e("SecondNDKApplication", result);
}
private static native String testMethod();
}
実行・デバッグについてはAndroid SDKで作成した通常のアプリケーションと特に変わりません。ただし、ネイティブ側についての確認は別途実施する必要があります。ネイティブ側、JAVA側を同時にデバッガで確認できるようにとも考えましたが、今のところまともな解決策が思い当たりません。