扫描二维码
随时随地手机看文章
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语言那种形式的接口。