扫描二维码
随时随地手机看文章
jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);static jobject g_class_loader = NULL;static jmethodID g_find_class_method = NULL;void on_load() { JNIEnv *env = get_jni_env(); if (!env) { return; } jclass capture_class = (*env)->FindClass(env, "com/captureandroid/BMMCaptureEngine"); jclass class_class = (*env)->GetObjectClass(env, capture_class); jclass class_loader_class = (*env)->FindClass(env, "java/lang/ClassLoader"); jmethodID class_loader_mid = (*env)->GetMethodID(env, class_class, "getClassLoader", "()Ljava/lang/ClassLoader;"); jobject local_class_loader = (*env)->CallObjectMethod(env, capture_class, class_loader_mid); g_class_loader = (*env)->NewGlobalRef(env, local_class_loader); g_find_class_method = (*env)->GetMethodID(env, class_loader_class, "findClass", "(Ljava/lang/String;)Ljava/lang/Class;");}
jclass find_class(const char *name) { JNIEnv *env = bmm_util_get_jni_env(); if (!env) { return NULL; } jclass ret = (*env)->FindClass(env, name); jthrowable exception = (*env)->ExceptionOccurred(env); if (exception) { (*env)->ExceptionClear(env); jstring name_str = (*env)->NewStringUTF(env, name); ret = (jclass)(*env)->CallObjectMethod(env, g_class_loader, g_find_class_method, name_str); (*env)->DeleteLocalRef(env, name_str); } return ret;}
typedef const struct JNINativeInterface *JNIEnv;
struct JNINativeInterface { void* reserved0; void* reserved1; void* reserved2; void* reserved3;
jint (*GetVersion)(JNIEnv *);
jclass (*DefineClass)(JNIEnv*, const char*, jobject, const jbyte*, jsize); jclass (*FindClass)(JNIEnv*, const char*); jobject (*AllocObject)(JNIEnv*, jclass); jobject (*NewObject)(JNIEnv*, jclass, jmethodID, ...); jobject (*NewObjectV)(JNIEnv*, jclass, jmethodID, va_list); jobject (*NewObjectA)(JNIEnv*, jclass, jmethodID, const jvalue*); ...};JavaVM类似struct JNIInvokeInterface { void* reserved0; void* reserved1; void* reserved2;
jint (*DestroyJavaVM)(JavaVM*); jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*); jint (*DetachCurrentThread)(JavaVM*); jint (*GetEnv)(JavaVM*, void**, jint); jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);};
typedef const struct JNIInvokeInterface* JavaVM;jint GetEnv(JavaVM *vm, void **env, jint version);// C语言jstring model_path = (*env)->NewStringUTF(env, path);// C jstring model_path = env->NewStringUTF(path);前面列出的JNIEnv是C语言形式,Java还单独为C 封装了一层JNIEnv,简化版代码:struct _JNIEnv { /* do not rename this; it does not seem to be entirely opaque */ const struct JNINativeInterface* functions;
#if defined(__cplusplus)
jint GetVersion(){ return functions->GetVersion(this); }
jclass FindClass(const char* name){ return functions->FindClass(this, name); }#endif}其实本质上还是调用的C语言那种形式的接口。