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中Dialog的使用详解

《Android中Dialog的使用详解》Dialog(对话框)是Android中常用的UI组件,用于临时显示重要信息或获取用户输入,本文给大家介绍Android中Dialog的使用,感兴趣的朋友一起... 目录android中Dialog的使用详解1. 基本Dialog类型1.1 AlertDialog(

Android Kotlin 高阶函数详解及其在协程中的应用小结

《AndroidKotlin高阶函数详解及其在协程中的应用小结》高阶函数是Kotlin中的一个重要特性,它能够将函数作为一等公民(First-ClassCitizen),使得代码更加简洁、灵活和可... 目录1. 引言2. 什么是高阶函数?3. 高阶函数的基础用法3.1 传递函数作为参数3.2 Lambda

Android自定义Scrollbar的两种实现方式

《Android自定义Scrollbar的两种实现方式》本文介绍两种实现自定义滚动条的方法,分别通过ItemDecoration方案和独立View方案实现滚动条定制化,文章通过代码示例讲解的非常详细,... 目录方案一:ItemDecoration实现(推荐用于RecyclerView)实现原理完整代码实现

Android App安装列表获取方法(实践方案)

《AndroidApp安装列表获取方法(实践方案)》文章介绍了Android11及以上版本获取应用列表的方案调整,包括权限配置、白名单配置和action配置三种方式,并提供了相应的Java和Kotl... 目录前言实现方案         方案概述一、 androidManifest 三种配置方式

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Android WebView无法加载H5页面的常见问题和解决方法

《AndroidWebView无法加载H5页面的常见问题和解决方法》AndroidWebView是一种视图组件,使得Android应用能够显示网页内容,它基于Chromium,具备现代浏览器的许多功... 目录1. WebView 简介2. 常见问题3. 网络权限设置4. 启用 JavaScript5. D

Android如何获取当前CPU频率和占用率

《Android如何获取当前CPU频率和占用率》最近在优化App的性能,需要获取当前CPU视频频率和占用率,所以本文小编就来和大家总结一下如何在Android中获取当前CPU频率和占用率吧... 最近在优化 App 的性能,需要获取当前 CPU视频频率和占用率,通过查询资料,大致思路如下:目前没有标准的

Android开发中gradle下载缓慢的问题级解决方法

《Android开发中gradle下载缓慢的问题级解决方法》本文介绍了解决Android开发中Gradle下载缓慢问题的几种方法,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧... 目录一、网络环境优化二、Gradle版本与配置优化三、其他优化措施针对android开发中Gradle下载缓慢的问

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干