说到JNIEnvExt这个类,其实是和JavaVMExt类似的,JavaVMExt是从JavaVM继承而来,而JNIEnvExt类则是从JNIEnv继承而来,类关系图和JavaVMExt也是类似的,下面我们直接从JNIEnv定义开始,下面所有分析的代码都是基于Android11_R17进行分析。
JNIEnv定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
#if defined(__cplusplus) // 如果是C++环境,JNIEnv其实就是_JNIEnv结构体的别名了 typedef _JNIEnv JNIEnv; ...... struct _JNIEnv { // 和JavaVMExt类似,结构体第一个成员变量是JNINativeInterface const struct JNINativeInterface* functions; #if defined(__cplusplus) // 和JavaVMExt类中方法的实现也是类似的,在方法体中通过调用functions的同名方法完成 jint GetVersion() { return functions->GetVersion(this); } jclass DefineClass(const char *name, jobject loader, const jbyte* buf, jsize bufLen) { return functions->DefineClass(this, name, loader, buf, bufLen); } jclass FindClass(const char* name) { return functions->FindClass(this, name); } jmethodID FromReflectedMethod(jobject method) ................. // JNIEnv提供了非常多的方法,我们在进行JNI编程是用到的方法都在这里有定义 |
和JavaVMExt
中的JNIInvokeInterface
就有点类似了,JNIEnvExt
则是使用了JNINativeInterface
,下面我们看看JNINativeInterface
里面的具体内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
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 (*NewGlobalRef)(JNIEnv*, jobject); void (*DeleteGlobalRef)(JNIEnv*, jobject); void (*DeleteLocalRef)(JNIEnv*, jobject); jboolean (*IsSameObject)(JNIEnv*, jobject, jobject); jobject (*NewLocalRef)(JNIEnv*, jobject); jint (*EnsureLocalCapacity)(JNIEnv*, jint); .......... |
JNINativeInterface
中定义的方法非常多,我们这里挑了一小部分出来,NewGlobalRef
、DeleteGlobalRef
这类方法是否有些似曾相识呢?这些方法在JNI编程的时候也会经常用到,其实就是在这里定义的。
JNIEnvExt创建过程
JNIEnvExt
的创建过程也和JavaVMExt
类似,最开始调用JNIEnvExt::Create
进行JNIEnvExt进行创建
1 2 3 4 5 6 7 8 |
JNIEnvExt* JNIEnvExt::Create(Thread* self_in, JavaVMExt* vm_in, std::string* error_msg) { std::unique_ptr<JNIEnvExt> ret(new JNIEnvExt(self_in, vm_in, error_msg)); if (CheckLocalsValid(ret.get())) { return ret.release(); } return nullptr; } |
关键地方也是调用new JNIEnvExt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
JNIEnvExt::JNIEnvExt(Thread* self_in, JavaVMExt* vm_in, std::string* error_msg) : self_(self_in), // 保存所在Thread vm_(vm_in), // 保存JavaVMExt local_ref_cookie_(kIRTFirstSegment), locals_(kLocalsInitial, kLocal, IndirectReferenceTable::ResizableCapacity::kYes, error_msg), monitors_("monitors", kMonitorsInitial, kMonitorsMax), critical_(0), check_jni_(false), runtime_deleted_(false) { MutexLock mu(Thread::Current(), *Locks::jni_function_table_lock_); // 判断是否需要开启check_jni操作 check_jni_ = vm_in->IsCheckJniEnabled(); // 这里进行JNINativeInterface的初始化 functions = GetFunctionTable(check_jni_); unchecked_functions_ = GetJniNativeInterface(); } |
接下来,我们看下开启check_jni_
和未开启check_jni_
的赋值情况
1 2 3 4 5 6 7 8 |
const JNINativeInterface* JNIEnvExt::GetFunctionTable(bool check_jni) { const JNINativeInterface* override = JNIEnvExt::table_override_; if (override != nullptr) { return override; } return check_jni ? GetCheckJniNativeInterface() : GetJniNativeInterface(); } |
如果启用了JNI检查,那么调用的是GetCheckJniNativeInterface
,否则就是GetJniNativeInterface
1 2 3 4 5 6 7 8 9 10 |
const JNINativeInterface* GetCheckJniNativeInterface() { return &gCheckNativeInterface; } const JNINativeInterface* GetJniNativeInterface() { return Runtime::Current()->GetJniIdType() == JniIdType::kPointer ? &JniNativeInterfaceFunctions<false>::gJniNativeInterface : &JniNativeInterfaceFunctions<true>::gJniNativeInterface; } |
和JavaVMExt
类似,放个结构体指针,启用JNI检查,指向gCheckNativeInterface
,否则指向gJniNativeInterface
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
const JNINativeInterface gCheckNativeInterface = { nullptr, // reserved0. nullptr, // reserved1. nullptr, // reserved2. nullptr, // reserved3. CheckJNI::GetVersion, CheckJNI::DefineClass, CheckJNI::FindClass, CheckJNI::FromReflectedMethod, CheckJNI::FromReflectedField, CheckJNI::ToReflectedMethod, .......... static constexpr JNINativeInterface gJniNativeInterface = { nullptr, // reserved0. nullptr, // reserved1. nullptr, // reserved2. nullptr, // reserved3. JNIImpl::GetVersion, JNIImpl::DefineClass, JNIImpl::FindClass, JNIImpl::FromReflectedMethod, JNIImpl::FromReflectedField, ............ |
JNIEnvExt的相关类的关系也是比较简单,这里先留个记忆,后面有遇到类似的需求再对细节进行拆解分析。