#include "DxLib.h"
#include <string.h>
int android_main( void )
{
JNIEnv *env ;
const ANativeActivity *NativeActivity ;
int InputEnd ;
char InputString[ 1024 ] ;
// 背景を灰色にする
SetBackgroundColor( 128,128,128 ) ;
// DXライブラリの初期化
if( DxLib_Init() < 0 ) return -1 ;
// 描画先を裏画面に変更
SetDrawScreen( DX_SCREEN_BACK ) ;
// アプリの NativeActivity を取得しておく
NativeActivity = GetNativeActivity() ;
// Java の関数 StartInputStringDialog の呼び出し
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー関数 StartInputStringDialog の ID を取得
jmethodID jmethodID_StartInputDialog = env->GetMethodID( jclass_MainActivity, "StartInputStringDialog", "()V" ) ;
// Java のクラス MainActivity のメンバー関数 StartInputStringDialog の呼び出し
env->CallVoidMethod( NativeActivity->clazz, jmethodID_StartInputDialog ) ;
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
}
// 入力が完了したかどうかのフラグを倒す
InputEnd = 0 ;
// メインループ
while( ProcessMessage() == 0 )
{
// 裏画面の内容をクリア
ClearDrawScreen() ;
// 入力が完了していなかったら Java のクラス MainActivity のメンバー変数 InputEnd と InputString の情報を取得する
if( InputEnd == 0 )
{
// JavaVM とソフト実行用スレッドを関連付け( C++ から Java の機能を使用するために必要 )
if( NativeActivity->vm->AttachCurrentThreadAsDaemon( &env, NULL ) != JNI_OK )
{
return -1 ;
}
// Java のクラス MainActivity を取得
jclass jclass_MainActivity = env->GetObjectClass( NativeActivity->clazz ) ;
// Java のクラス MainActivity のメンバー変数 InputEnd の ID を取得
jfieldID jfieldID_InputEnd = env->GetFieldID( jclass_MainActivity, "InputEnd", "I" ) ;
// Java のクラス MainActivity のメンバー変数 InputEnd の値をローカル変数 InputEnd に代入
InputEnd = env->GetIntField( NativeActivity->clazz, jfieldID_InputEnd ) ;
// InputEnd が 1 になっていたら入力が完了しているので InputString の値を取得する
if( InputEnd == 1 )
{
// Java のクラス MainActivity のメンバー変数 InputString の ID を取得
jfieldID jfieldID_InputString = env->GetFieldID( jclass_MainActivity, "InputString", "Ljava/lang/String;" ) ;
// Java のクラス MainActivity のメンバー変数 InputString の jstring オブジェクトを取得
jstring jstring_InputString = ( jstring )env->GetObjectField( NativeActivity->clazz, jfieldID_InputString ) ;
// Java のクラス MainActivity のメンバー変数 InputString の jstring から C++ 用の文字列のアドレスを取得
const char *chars_InputString = env->GetStringUTFChars( jstring_InputString, NULL ) ;
// 文字列をローカル変数 InputString にコピー
strcpy( InputString, chars_InputString ) ;
// Java のクラス MainActivity のメンバー変数 InputString の jstring から取得した C++ 用の文字列のアドレスを解放
env->ReleaseStringUTFChars( jstring_InputString, chars_InputString ) ;
// Java のクラス MainActivity のメンバー変数 InputString の jstring オブジェクトの参照を削除
env->DeleteLocalRef( jstring_InputString ) ;
}
// Java のクラス MainActivity の参照を削除
env->DeleteLocalRef( jclass_MainActivity ) ;
// JavaVM とソフト実行用スレッドの関連付け終了
NativeActivity->vm->DetachCurrentThread() ;
}
// InputEnd と InputString の状態を画面に描画
DrawFormatString( 0, 100, GetColor( 255,255,255 ), "InputEnd:%d InputString:%s", InputEnd, InputString ) ;
// 裏画面の内容を表画面に反映
ScreenFlip() ;
}
// DXライブラリの後始末
DxLib_End();
// ソフトの終了
return 0;
}
以上です。
これでプロジェクトを実行すると、起動と同時に文字列入力ダイアログが現われ、文字列を入力して OK ボタンを押すと
画面に入力した文字列が表示されると思います。
詳細は割愛しますが、C++ から Java にアクセスする基本的な流れは。
① AttachCurrentThreadAsDaemon でソフト実行用スレッドと JavaVM を関連付け、JNIEnv も取得。
② GetObjectClass でアプリの Java クラスを取得。
③ GetMethodID や GetFieldID で Java の関数や変数の ID を取得。
④ Call???Method や Get???Field で Java の関数の呼び出しや変数の値を取得。
⑤ DeleteLocalRef で Get???Field で取得したオブジェクト系の変数の参照を削除。
⑥ DeleteLocalRef で GetObjectClass で取得したアプリの Java クラスの参照を削除。
⑦ DetachCurrentThread でソフト実行用スレッドと JavaVM の関連付けを終了。
となります。
C++ と Java でのやり取りを行う機能( JNI( Java Native Interface ) ) の詳しい扱い方については、検索サイトで
『Android Java JNI』などのキーワードで検索して調べてみてください。
戻る