Android中关于JNI 的学习(一)对于JNIEnv的一些认识

2024-06-14 15:08
文章标签 android 学习 认识 jni jnienv

本文主要是介绍Android中关于JNI 的学习(一)对于JNIEnv的一些认识,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一个简单的样例让我们初步地了解JNI的作用,可是关于JNI中的一些概念还是须要了解清楚,才可以更好的去利用它来实现我们想要做的事情。

那么C++和Java之间的是怎样通过JNI来进行互相调用的呢?

我们知道。在Android中,当Java文件被编译成dex文件之后,会由类载入器载入到Dalvik VM(DVM)中,由DVM来进行解释,翻译成机器语言之后,才干由机器来执行。

而对于C/C++来说,其源码经由Android提供的NDK工具包,能够编译成可运行动态库(即.so文件)。之后。Java和C++之间就能够进行通讯了。

那么,在这里,能够想像,Java的Dex字节码和C/C++的so库肯定是同一时候执行在一个DVM之中。它们是共同使用一个进程空间的,否则,它们怎么彼此沟通呢?

所以在这里,一个关键的中间区域就是Dalvik VM。而对于C/C++,当它们也被载入进DVM之后,由C/C++实现的函数方法等都会被载入在DVM中的函数表中。

假设想要在C/C++中调用函数,它们必需要有个东西可以让其訪问到这个虚拟机中的函数表。

而这个东西就是JNIEnv *。

当我们利用javah生成的C/C++的头文件的时候。例如以下:

JNIEXPORT jstring JNICALL Java_com_lms_jni_HwDemo_printHello(JNIEnv *e, jobject j)
{return (**e).NewStringUTF(e,"Hello from T" );
}

我们能够看到这种方法有两个參数。当中第一个就是JNIEnv *。而我们在Java端定义这种方法的时候。是没有參数的,例如以下:

public native String printHello();

那么这个JNIEnv是干什么用的?
事实上从这个參数的名称就能够看到,就是指JNI的执行环境,我认为它就是对Java虚拟环境的一个引用。在Android中。就是指Dalvik VM。
參考jni.h文件里关于JNIEnv的定义,例如以下(对于C和C++。它的定义有点不一样):
struct _JNIEnv;
struct _JavaVM;
typedef const struct JNINativeInterface* C_JNIEnv;#if defined(__cplusplus)
typedef _JNIEnv JNIEnv; //C++中JNIEnv的类型
typedef _JavaVM JavaVM; 
#else
typedef const struct JNINativeInterface* JNIEnv; //C中JNIEnv的类型
typedef const struct JNIInvokeInterface* JavaVM;
#endif

在C中,我们能够看到JNIEnv的类型就是JNINativeInterface* 。是一个指针类型,那么在C++中呢,_JNIEnv是什么样的呢?
struct _JNIEnv {/* do not rename this; it does not seem to be entirely opaque */const struct JNINativeInterface* functions;

而对于C++来说。 _JNIEnv是一个结构体。里面包括了JNINativeInterface*的结构。
所以从这里也能够看到。对于C和C++来说,它们引用JNIEnv中的方法是有一点不一样的。 总的来说,JNIEnv。无论是C。还是C++,事实上关键都是JNINativeInterface的这个结构。
我们能够简单看一下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);

能够看到在它当中定义了非常多的函数指针,而通过这些定义。JNI层事实上就获得了对DVM的引用,通过定义的这些函数指针。能够定位到虚拟机中的 JNI 函数表,从而实现JNI层在DVM中的函数调用。
所以。可以这样理解,事实上JNIEnv,就是对DVM执行环境中C/C++函数的一个引用。而也正由于此,当C/C++想要在DVM中调用函数的时候。由于其是在DVM的环境中,所以它们必须通过JNIEnv* 这个參数来获得这些方法,之后才可以使用。


那么这个JNIEnv是什么时候产生的呢?
当Android中第一个Java线程要调用本地的C/C++代码的时候。DVM就会为该线程产生一个JNIEnv*的指针。

而每个线程在和C/C++互相调用的时候。其相应的JNIEnv 也是相互独立。


嗯。结束。

这篇关于Android中关于JNI 的学习(一)对于JNIEnv的一些认识的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1060748

相关文章

Android WebView的加载超时处理方案

《AndroidWebView的加载超时处理方案》在Android开发中,WebView是一个常用的组件,用于在应用中嵌入网页,然而,当网络状况不佳或页面加载过慢时,用户可能会遇到加载超时的问题,本... 目录引言一、WebView加载超时的原因二、加载超时处理方案1. 使用Handler和Timer进行超

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

每天认识几个maven依赖(ActiveMQ+activemq-jaxb+activesoap+activespace+adarwin)

八、ActiveMQ 1、是什么? ActiveMQ 是一个开源的消息中间件(Message Broker),由 Apache 软件基金会开发和维护。它实现了 Java 消息服务(Java Message Service, JMS)规范,并支持多种消息传递协议,包括 AMQP、MQTT 和 OpenWire 等。 2、有什么用? 可靠性:ActiveMQ 提供了消息持久性和事务支持,确保消

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]