作業中のAndroidStudioプロジェクトでJNIを使用しています。現在、これに似たC ++ライブラリがあります。
#include <jni.h>
...
extern "C" {
JNIEXPORT jobject JNICALL Java_com_cerbyarms_cerbyarms_esra_camera_CameraActivity_FindFeatures(JNIEnv* env, jobject, jlong maskMat)
{
...
jclass rectClass = env->FindClass("org/opencv/core/Rect");
jmethodID rectID = env->GetMethodID(rectClass, "<init>", "(IIII)V");
return env->NewObject(rectClass, rectID, x, y, width, height);
}
}
これは機能します。ただし、非効率的です。これが実行されるたびに、rectClassはクラスを再検索する必要があり、プログラム内で一定のままである他の変数は、関数FindFeatures
が呼び出されるたびに再計算および再定義する必要があります。
Stack Overflowでこの回答に出くわしました(これは、私がやろうとしていることの例を示しているという事実を除けば、この質問とは関係ありません)。これは、JNIを使用する場合のネイティブファイルの異なるレイアウトを示しています。
こんな感じでした
static jclass java_util_ArrayList;
static jmethodID java_util_ArrayList_;
jmethodID java_util_ArrayList_size;
jmethodID java_util_ArrayList_get;
jmethodID java_util_ArrayList_add;
static thread_local JNIEnv* env;
void init() {
java_util_ArrayList = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));
java_util_ArrayList_ = env->GetMethodID(java_util_ArrayList, "<init>", "(I)V");
java_util_ArrayList_size = env->GetMethodID (java_util_ArrayList, "size", "()I");
java_util_ArrayList_get = env->GetMethodID(java_util_ArrayList, "get", "(I)Ljava/lang/Object;");
java_util_ArrayList_add = env->GetMethodID(java_util_ArrayList, "add", "(Ljava/lang/Object;)Z");
}
std::vector<std::string> java2cpp(jobject arrayList) {
jint len = env->CallIntMethod(arrayList, java_util_ArrayList_size);
std::vector<std::string> result;
result.reserve(len);
for (jint i = 0; i < len; i++) {
jstring element = static_cast<jstring>(env->CallObjectMethod(arrayList, java_util_ArrayList_get, i));
const char* pchars = env->GetStringUTFChars(element, nullptr);
result.emplace_back(pchars);
env->ReleaseStringUTFChars(element, pchars);
env->DeleteLocalRef(element);
}
}
これは、一度だけ宣言および計算されたように見える高価で定数の変数を持つネイティブファイルを示しています。
Android Studio IDEのみを使用して同様のことを実現するにはどうすればよいですか?Android Studio IDEの設定で外部ツールを設定する必要はありませんが、コードをコンパイルするたびにAndroidStudioとCMDなどを切り替え続けたくありません。
理想的には、これMake Project
はヒットしたときにすべて正しく処理できます。これはAndroidStudio 3で可能ですか?
あなたは100%正しいです、いくつかのJNI値はキャッシュされて再利用されるように頼みます。クラス参照とメソッドIDは良い例です。ことを覚えておいてくださいFindClassが()が必要なので、地元の参照を返します()NewGlobalRefを各クラスについて、あなたはキャッシュに保持します。
Android Studioはこのセットアップを支援しません。また、このようなリファクタリングを実行できる信頼性の高いツールを私は知りません。グッドプラクティスは、WebRTCJNIラッパーやSpotifyJNIヘルパーなどのオープンソースコードから学ぶことができます。
Android Studioは、キャッシュされたオブジェクトや変換などではなく、ネイティブメソッドのみを追跡できます。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加