600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > Android JNI和NDK学习(二):JNIEnv 和 JavaVM

Android JNI和NDK学习(二):JNIEnv 和 JavaVM

时间:2020-01-04 00:15:13

相关推荐

Android JNI和NDK学习(二):JNIEnv 和 JavaVM

概述

上篇学习了NDK相关知识,这篇继续学习JNI相关知识,这篇文章仅作为笔记,以防以后忘记

JNI的数据类型和类型描述符

在JNI开发中,java的数据类型并不能直接在JNI上直接使用,需要有一定的转化,比如java中的int在JNI中就是jint,下面我们来学习下数据类型

基本数据类型

引用数据类型

其实大部分就是在java的数据类型的前面加上了小写j来表示jni的数据类型

类型描述符

在JVM虚拟机中,存储数据类型名称的时候,是使用指定的描述符来使用,而不是我们使用的int,float来储存

表示一个string类

就是L+全类名,其中.换成/,最后加上

表示数组

表示方法

JNIEnv 和 JavaVM

JavaVM

javaVM是java虚拟机在jni层的代表,一个进程只有一个JavaVM,所有的线程共用一个JavaVM

我们来看下JavaVM结构体

struct _JavaVM {const struct JNIInvokeInterface* functions;#if defined(__cplusplus)jint DestroyJavaVM(){return functions->DestroyJavaVM(this); }jint AttachCurrentThread(JNIEnv** p_env, void* thr_args){return functions->AttachCurrentThread(this, p_env, thr_args); }jint DetachCurrentThread(){return functions->DetachCurrentThread(this); }jint GetEnv(void** env, jint version){return functions->GetEnv(this, env, version); }jint AttachCurrentThreadAsDaemon(JNIEnv** p_env, void* thr_args){return functions->AttachCurrentThreadAsDaemon(this, p_env, thr_args); }#endif /*__cplusplus*/};

这里值分析C++版的,可以看到所有的方法都是JNIInvokeInterface实现的,我们看下这个结构体

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

我们看到JNIInvokeInterface结构体包含5个函数,看方法名大概能知道他们有什么作用,比如:GetEnv函数获取JNIEnv指针

当从Java层到Native层开发时,他会自动创建JavaVM对象,但是当Native层到Java层开发时,需要我们主动创建JavaVM对象,我们可以用下面的函数创建

jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args);第一个参数:指向JavaVM *的指针,函数调用成功会给JavaVM *赋值第二个参数:指向JNIEnv *的指针,函数调用成功会给JNIEnv *赋值第三个参数:是指向JavaVMInitArgs的指针,是初始化虚拟机的参数

JNIEnv

JNIEnv是一个线程相关的结构体,该结构体代表了java在本线程的执行环境

JavaVM:JavaVM是java虚拟机在jni层的代表,全局只有一个

JNIEnv:每个线程都有一个,jni可能有多个JNIEnv

native环境创建线程,如果要访问jni,需要调用AttachCurrentThread方法进行关联,使用DetachCurrentThread接触关联

_JavaVM结构体中,有一个方法getEnv()可以获取JNIEnv

jint GetEnv(JavaVM *vm, void **env, jint version);第一个参数:JavaVM虚拟机对象第二个参数:指向JNIEnv的指针第三个参数:jni的版本,根据jdk的版本,目前有四种值,分别为 JNI_VERSION_1_1, JNI_VERSION_1_2, JNI_VERSION_1_4, JNI_VERSION_1_6

函数调用成功会给JNIEnv赋值

JNIEnv的作用

我们先看下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 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){return functions->FromReflectedMethod(this, method); }jfieldID FromReflectedField(jobject field){return functions->FromReflectedField(this, field); }...省略很多函数}

我们可以看到函数的实现最终还是交给了JNINativeInterface去实现,我们再看下这个结构体

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*);jmethodID (*FromReflectedMethod)(JNIEnv*, jobject);jfieldID (*FromReflectedField)(JNIEnv*, jobject);/* spec doesn't show jboolean parameter */jobject(*ToReflectedMethod)(JNIEnv*, jclass, jmethodID, jboolean);jclass(*GetSuperclass)(JNIEnv*, jclass);jboolean (*IsAssignableFrom)(JNIEnv*, jclass, jclass);/* spec doesn't show jboolean parameter */jobject(*ToReflectedField)(JNIEnv*, jclass, jfieldID, jboolean);jint (*Throw)(JNIEnv*, jthrowable);jint (*ThrowNew)(JNIEnv *, jclass, const char *);jthrowable (*ExceptionOccurred)(JNIEnv*);void (*ExceptionDescribe)(JNIEnv*);void (*ExceptionClear)(JNIEnv*);void (*FatalError)(JNIEnv*, const char*);...省略很多的方法}

这个结构体的作用是操作java层的入口,具体有俩个作用

调用java函数:使用JNIEnv调用java中的代码操作java对象:java对象传入jni层是jstring,可以使用JNIEnv来操作这个对象

参考:

https://juejin.im/post/5d19bf3f6fb9a07eaa229349

/p/87ce6f565d37

/afei__/article/details/80986203

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。