この記事は、JNI メソッドに基づいています -- C++ プロジェクトで Java インターフェイスにアクセスする方法 (1)
別の言い方をすると、この記事では主にコンテキスト Context を取得する方法について説明します。
インターネット上の多くの記事では、ActivityThread を介して現在の Context を取得することについて説明しており、記事は非常に古く、新しい Android バージョンには適していないため、ローカルでテストに合格しましたが、FindClass は ActivityThread をまったく見つけることができなかったので、この記事を書きました。
AudioManagerの取得を例に説明すると以下のようになります。
Native プロジェクトなので、アプリケーションの起動後に android_main 関数が呼び出されます (プロジェクト内に存在する場合もあります)。この関数では、通常、JVM が初期化されます。
void android_main(struct android_app* アプリ) { JNIEnv* 環境; //Env赋值app->アクティビティ->vm->AttachCurrentThread(&Env, nullptr); app->userData = &appState; app->onAppCmd = app_handle_cmd; jobject activityInstance = app->activity->clazz; JavaVM* jvm = アプリ->アクティビティ->vm;
Javaの方法は次のとおりです。
//AudioManager mAudioManager = (AudioManager) getContext() .getSystemService(Context.AUDIO_SERVICE);
以下は、getContext() がどのように取得されるかを示します。
対応する C++ 実装は次のとおりです。
jclass Context = Env->FindClass("android/content/Context");
jmethodID getSystemService = Env->GetMethodID(Context, "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
jstring audio = Env->NewStringUTF("audio");
__android_log_print(ANDROID_LOG_DEBUG, "シャンシャン", "getSystemService");//AudioManagerServiceを取得、戻り値はAudioManager
//最初のエントリ activityInstance は現在のコンテキスト
ジョブジェクトです audioManagerService = Env->CallObjectMethod( activityInstance , getSystemService, audio);