安卓10源码学习开发定制(37)Art虚拟机中JNINativeInterface初始化流程分析

admin 2023年5月18日09:44:29评论29 views字数 3638阅读12分7秒阅读模式

1.JNIEnv初始化

   在文章"安卓10源码学习开发定制(36)Art虚拟机中JavaVM &JNIEnv 的初始化流程"中已经分析了JNIEnv的初始化构造流程。最终JNIEnv初始化构造是在文件 artruntimethread.cc中的类中进行构造,关键代码如下:


bool Thread::Init(ThreadList* thread_list, JavaVMExt* java_vm, JNIEnvExt* jni_env_ext) {  ...  if (jni_env_ext != nullptr) {    ...    tlsPtr_.jni_env = jni_env_ext;  } else {    std::string error_msg;    //创建JNIEnv结构并存储到线程局部存储变量中    tlsPtr_.jni_env = JNIEnvExt::Create(this, java_vm, &error_msg);    ...  }  ...}

     接下来分析JNIEnvExt中的JNINativeInterface是如何初始化的。


2.JNINativeInterface初始化流程分析


     JNIEnvExt类的文件路径为:

artruntimejnijni_env_ext.cc

   (1).JNIEnvExt中的调用分析

          在以上分析中JNIEnv通过调用JNIEnvExt::Create进行创建,在JNIEnvExt中的Create方法实现逻辑如下:

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));  ...}

      在以上代码中使用了new JNIEnvExt(self_in, vm_in, error_msg)进行初始化,下面是JNIEnvExt构造函数实现:

JNIEnvExt::JNIEnvExt(Thread* self_in, JavaVMExt* vm_in, std::string* error_msg)    : self_(self_in),      vm_(vm_in),      local_ref_cookie_(kIRTFirstSegment),      locals_(kLocalsInitial, kLocal, IndirectReferenceTable::ResizableCapacity::kYes, error_msg),      monitors_("monitors", kMonitorsInitial, kMonitorsMax),      critical_(0),      check_jni_(false),      runtime_deleted_(false) {  ...  //这个地方进行了JNINativeInterface的初始化,functions 定义在JNIEnv中  functions = GetFunctionTable(check_jni_);}

     在以上代码调用中调用了GetFunctionTable()方法初始化JNIEnv中的functions变量,JNIEnv中的functions定义如下:

struct _JNIEnv {    /* do not rename this; it does not seem to be entirely opaque */    const struct JNINativeInterfacefunctions;    ...}

     接下来分析一下GetFunctionTable方法中的实现。GetFunctionTable逻辑代码如下:

const JNINativeInterface* JNIEnvExt::GetFunctionTable(bool check_jni) {  ...  //当前会根据chck_jni调用不同的JNINativeInterface初始化接口  return check_jni ? GetCheckJniNativeInterface() : GetJniNativeInterface();}

     check_jni在编译eng版本的时候会被打开,所以这个地方我们只分析useruserdebug版本的流程。所以接下来将会执行GetJniNativeInterface方法。

    根据源码定位GetJniNativeInterface方法定义在如下文件:

artruntimejnijni_internal.h

   定义的代码内容如下:

const JNINativeInterface* GetJniNativeInterface();

    该方法实现文件路径位于:

artruntimejnijni_internal.cc

   接下来分析jni_internal.cc中的流程。


  (2).jni_internal.cc中的调用分析

       在该文件中GetJniNativeInterface方法实现如下:

const JNINativeInterface* GetJniNativeInterface() {  return &gJniNativeInterface;}

     有以上代码分析可知返回的是gJniNativeInterface变量的值,该变量定义如下:

const JNINativeInterface gJniNativeInterface = {  nullptr,  // reserved0.  nullptr,  // reserved1.  nullptr,  // reserved2.  nullptr,  // reserved3.  JNI::GetVersion,  JNI::DefineClass,  JNI::FindClass,  ...}

         有以上代码可以知道该变量为常量,使用一些列JNI类中的方法填充JNINativeInterface接口,从而完成JNIEnv中的JNINativeInterface初始化。

    在jni_internal.cc中可以找到类JNI的定义实现。如下:

class JNI { public:  static jint GetVersion(JNIEnv*) {    return JNI_VERSION_1_6;  }
static jclass DefineClass(JNIEnv*, const char*, jobject, const jbyte*, jsize) { LOG(WARNING) << "JNI DefineClass is not supported"; return nullptr; }
static jclass FindClass(JNIEnv* env, const char* name) { CHECK_NON_NULL_ARGUMENT(name); Runtime* runtime = Runtime::Current(); ClassLinker* class_linker = runtime->GetClassLinker(); std::string descriptor(NormalizeJniClassDescriptor(name)); ScopedObjectAccess soa(env); ObjPtr<mirror::Class> c = nullptr; if (runtime->IsStarted()) { StackHandleScope<1> hs(soa.Self()); Handle<mirror::ClassLoader> class_loader(hs.NewHandle(GetClassLoader(soa))); c = class_linker->FindClass(soa.Self(), descriptor.c_str(), class_loader); } else { c = class_linker->FindSystemClass(soa.Self(), descriptor.c_str()); } return soa.AddLocalReference<jclass>(c); }  ... }

      以上代码可以看到JNI中真正实现了JNIEnv结构体中JNINativeInterface接口,我们平时调用的接口比如FindClass最终调用的是JNI::FindClass




3.总结

   

    art虚拟机中的JNIEnv中的各种接口最终实现位于"jni_internal.cc"中的class  JNI中实现。

    如果我们需要在系统中进行JNI trace,就可以在jni_internal.cc中进行日志输出。


如果你对安卓相关的开发学习感兴趣:

安卓10源码学习开发定制(37)Art虚拟机中JNINativeInterface初始化流程分析 点击屏末  | 获取更多文章列表信息



扫描下方二维码关注公众号

安卓10源码学习开发定制(37)Art虚拟机中JNINativeInterface初始化流程分析

原文始发于微信公众号(哆啦安全):安卓10源码学习开发定制(37)Art虚拟机中JNINativeInterface初始化流程分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2023年5月18日09:44:29
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   安卓10源码学习开发定制(37)Art虚拟机中JNINativeInterface初始化流程分析https://cn-sec.com/archives/787034.html

发表评论

匿名网友 填写信息