.
jni.h文件 : 了解 JNI 需要配合 jni.h 文件, jni.h 是 Google NDK 中的一个文件, 位置是 $/android-ndk-r9d/platforms/android-19/arch-arm/usr/include/jni.h ;
1. JNIEnv 作用
JNIEnv 概念 : 是一个线程相关的结构体, 该结构体代表了 Java 在本线程的运行环境 ;
JNIEnv 与 JavaVM : 注意区分这两个概念;
-- JavaVM : JavaVM 是 Java虚拟机在 JNI 层的代表, JNI 全局只有一个;
-- JNIEnv : JavaVM 在线程中的代表, 每个线程都有一个, JNI 中可能有很多个 JNIEnv;
JNIEnv 作用 :
-- 调用 Java 函数 : JNIEnv 代表 Java 运行环境, 可以使用 JNIEnv 调用 Java 中的代码;
-- 操作 Java 对象 : Java 对象传入 JNI 层就是 Jobject 对象, 需要使用 JNIEnv 来操作这个 Java 对象;
2. JNIEnv 的创建和释放
JNIEnv 创建 和 释放:从 JavaVM 获得 : 下面是 JavaVM 结构体的代码,
-- C语言 中来源 : JNIInvokeInterface 是 C 语言环境中的 JavaVM 结构体, 调用(*AttachCurrentThread)(JavaVM*, JNIEnv**, void*) 方法, 可以获取 JNIEnv结构体;
-- C++ 中来源 :_JavaVM 是 C++ 中的 JavaVM 结构体, 调用jint AttachCurrentThread(JNIEnv** p_env, void* thr_args) 方法, 可以获取 JNIEnv 结构体;
-- C语言 中释放 : 调用 JavaVM结构体 (JNIInvokeInterface) 中的(*DetachCurrentThread)(JavaVM*)方法, 可以释放本线程中的 JNIEnv;
-- C++ 中释放 : 调用 JavaVM 结构体 (_JavaVM) 中的jint DetachCurrentThread(){ return functions->DetachCurrentThread(this); } 方法, 即可释放 本线程中的 JNIEnv ;
/*
* JNI invocation interface.
*/
struct JNIInvokeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
jint (*DestroyJavaVM)(JavaVM*);
/* 创建 JNIEnv , 每个线程创建一个 */
jint (*AttachCurrentThread)(JavaVM*, JNIEnv**, void*);
/* 释放本线程的 JNIEnv */
jint (*DetachCurrentThread)(JavaVM*);
jint (*GetEnv)(JavaVM*, void**, jint);
jint (*AttachCurrentThreadAsDaemon)(JavaVM*, JNIEnv**, void*);
};
/*
* C++ version.
*/
struct _JavaVM {
const struct JNIInvokeInterface* functions;
#if defined(__cplusplus)
jint DestroyJavaVM()
{ return functions->DestroyJavaVM(this); }
/* 创建 JNIEnv , 每个线程创建一个 , 调用的C语言结构提中的方法, C 与 C++ 方法相同 */
jint AttachCurrentThread(JNIEnv** p_env, void* thr_args)
{ return functions->AttachCurrentThread(this, p_env, thr_args); }
/* 释放本线程的 JNIEnv , 调用的C语言结构提中的方法, C 与 C++ 方法相同 */
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*/
};
3. JNIEnv 体系结构
线程相关: JNIEnv 是线程相关的, 即 在 每个线程中 都有一个 JNIEnv 指针, 每个JNIEnv 都是线程专有的, 其它线程不能使用本线程中的 JNIEnv, 线程 A 不能调用 线程 B 的 JNIEnv;
JNIEnv 不能跨线程 :
-- 当前线程有效 : JNIEnv 只在当前线程有效, JNIEnv 不能在 线程之间进行传递, 在同一个线程中, 多次调用 JNI层方法, 传入的 JNIEnv 是相同的;
-- 本地方法匹配多JNIEnv : 在 Java 层定义的本地方法, 可以在不同的线程调用, 因此 可以接受不同的 JNIEnv;
JNIEnv 结构 : 由上面的代码可以得出, JNIEnv 是一个指针, 指向一个线程相关的结构, 线程相关结构指向 JNI 函数指针 数组, 这个数组中存放了大量的 JNI 函数指针, 这些指针指向了具体的 JNI 函数;
4. 分析 JNIEnv 相关代码
JNIEnv 定义的相关代码:
/* 声明结构体, 以便在下面能够使用 */
struct _JNIEnv;
struct _JavaVM;
/* 声明 C 语言环境中的 JNIEnv 为 C_JNIEnv 指针, 指向 JNINativeInterface 结构体 */
typedef const struct JNINativeInterface* C_JNIEnv;
#if defined(__cplusplus)
/* C++环境下, JNIEnv 是结构体 */
typedef _JNIEnv JNIEnv;
typedef _JavaVM JavaVM;
#else
/* C语言环境下, JNIEnv是指针 */
typedef const struct JNINativeInterface* JNIEnv;
typedef const struct JNIInvokeInterface* JavaVM;
#endif
--JNINativeInterface 结构体 : 该结构体中定义了大量的函数指针, 这些函数指针 指向 与 Java 相关的变量有关的函数, 如果是 C 语言环境中, JNIEnv 就是指向 该结构体的指针;
-- _JNIEnv 结构体 : C++ 环境中的 JNIEnv 就是该结构体, 该结构体中封装了 一个JNINativeInterface 结构体指针, 即 C++ 中的 JNIEnv 要比 C 语言中的要多, 并且 完全兼容 C 语言中的 JNIEnv;
-- _JavaVM 结构体 : 该结构体 是 Java 虚拟机 在 JNI 中的代表, 整个 JNI 层 只存在一个 该 虚拟机映射;
JNINativeInterface 源码(删减过) : 省略后的, 其中定义了 与 Java 有关的相关方法, 都是 指向对应函数的函数指针;
-- 解析 JNIEnv* : C语言环境中的typedef const struct JNINativeInterface* JNIEnv , JNIEnv* env 等价于JNINativeInterface** env1 (指向结构体地址的指针), 要想 根据 二级指针 env1 获取JNINativeInterface 结构体中定义的函数指针, 首先获取 指向结构体的一级指针, 获取方法是 (*env1), 因此调用其中的函数指针指向的方法要这样 : (*env1)->FindClass(JNIEnv*, const char*);
/*
* Table of interface function pointers.
*/
struct JNINativeInterface {
void* reserved0;
void* reserved1;
void* reserved2;
void* reserved3;
jint (*GetVersion)(JNIEnv *);
... ...
jobject (*NewDirectByteBuffer)(JNIEnv*, void*, jlong);
void* (*GetDirectBufferAddress)(JNIEnv*, jobject);
jlong (*GetDirectBufferCapacity)(JNIEnv*, jobject);
/* added in JNI 1.6 */
jobjectRefType (*GetObjectRefType)(JNIEnv*, jobject);
};
_JNIEnv 源码(删减过) : 该源码中有一个JNINativeInterface 结构体指针, 说明 C++ 环境的 JNIEnv 是在 C 语言环境的 JNIEnv 下扩展的;
-- 解析 JNIEnv* : 定义是这样的typedef _JNIEnv JNIEnv, JNIEnv* env 等价于 _JNIEnv* env1, 因此调用 _JNIEnv 中定义的函数指针指向的函数的时候, 只需要 使用 env1->FindClass(JNIEnv*, const char*) 即可;
/*
* C++ object wrapper.
*
* This is usually overlaid on a C struct whose first element is a
* JNINativeInterface*. We rely somewhat on compiler behavior.
*/
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); }
... ...
jlong GetDirectBufferCapacity(jobject buf)
{ return functions->GetDirectBufferCapacity(this, buf); }
/* added in JNI 1.6 */
jobjectRefType GetObjectRefType(jobject obj)
{ return functions->GetObjectRefType(this, obj); }
#endif /*__cplusplus*/
};
分享到:
相关推荐
Android系统以其开源性和灵活性吸引了大量的开发者,而JNI(Java Native Interface)则是Android平台中连接Java层与原生C/C++代码的重要桥梁。JNI允许开发者在Android应用中调用本地库,实现性能优化或者利用已有的C...
Android NDK和JNI是Android平台下进行原生代码开发的重要工具,主要面向希望利用C/C++等低级语言实现高效能计算或者复用已有的C库的开发者。本教程将详细解析这两个技术,并通过实例帮助你掌握它们的核心概念和应用...
JNI在Android开发中扮演着重要的角色,特别是在需要高效计算、调用系统底层库或者利用硬件特性时。周工的"android_jni开发文档"应该详细介绍了使用JNI进行Android开发的过程。 JNI开发流程主要包括以下几个步骤: ...
《Android之JNI实战指南》 在移动开发领域,Android与C/C++的交互是一个重要的技术环节,这主要得益于JNI(Java Native Interface)的存在。JNI允许Java代码与其他编程语言(如C/C++)编写的代码进行交互,使得我们...
本文将深入解析Android系统中的JNI编程,包括其基本概念、开发步骤、注意事项以及实际应用。 1. JNI基本概念 JNI是Java平台提供的一种接口,它定义了一套标准的函数调用规范,使得Java代码可以调用C/C++编写的功能...
在Android开发中,JNI常用于提升性能、调用系统库或者实现特定的硬件功能。本教程聚焦于在Android Studio环境下使用JNI进行学习,涵盖了基本数据类型转化、引用数据类型转化以及JSON格式数据类型的转化。 首先,...
JNI在Android开发中扮演着重要角色,尤其是在性能优化、调用系统底层库或者实现特定功能时。本文将深入探讨JNI的概念、工作原理,并结合一个名为"MyJni"的示例项目,详细介绍如何在Android中使用JNI。 1. **JNI基础...
Android Studio JNI_NDK开发实例是Android应用开发中的一个重要领域,涉及到Java与原生代码(C/C++)的交互。JNI(Java Native Interface)是Java平台的一部分,它允许Java代码和其他语言写的代码进行交互。NDK...
在Android开发中,JNI(Java Native Interface)是一个关键的技术,它允许Java代码和其他语言写的代码进行交互。JNI在安卓USB开发中尤其重要,特别是在处理硬件交互、提高性能或利用特定硬件功能时,如读取ISO7816...
根据提供的文件信息,本文将详细解析与Android JNI相关的知识点,主要围绕Java Native Interface(JNI)的概念、作用及其在Android开发中的应用进行展开。 ### Java Native Interface (JNI) 简介 Java Native ...
在Android开发中,JNI通常与NDK一起使用,以便将计算密集型的任务移到C++中,利用其高效的运算能力。下面我们将深入探讨Android NDK与JNI的应用及实现过程。 **JNI基础知识** 1. **JNI头文件**:编写JNI代码前,...
Android JNI(Java Native Interface)开发是Android系统中用于连接Java代码和本地(通常是C或C++)代码的技术。JNI允许开发者在Java应用程序中利用本地代码的高性能和灵活性,同时保持Java的跨平台特性。以下是对...
在Android开发中,NDK(Native Development Kit)是Google提供的一套工具,允许开发者使用C和C++等原生代码来编写部分应用,以提升性能和处理特定的底层任务。当我们需要在Android NDK环境中获取系统的使用时间时,...
### Android通过JNI调用驱动程序(完全解析实例) #### 概述 在Android开发中,经常需要使用到JNI(Java Native Interface,Java本机接口)技术来实现Java代码与C/C++代码之间的交互。这对于想要利用低级语言的...
### Jni详细解析 #### 一、Jni简介与应用场景 JNI(Java Native Interface)是Java平台标准的一部分,它允许Java代码与其他语言写的代码进行交互。JNI在Android开发中的应用场景非常广泛,尤其当涉及到高性能计算...
在Android应用开发中,如果需要获取设备的内存状态,可以通过JNI来实现。 首先,我们需要了解JNI的基本概念。JNI提供了一套接口,使得Java代码可以调用本地(Native)代码,也就是非Java语言编写的代码。在Android...
本指南将详细解析Android JNI的操作流程和核心概念,帮助开发者深入理解并熟练运用JNI技术。 1. **JNI简介** JNI是Java平台的一部分,它为Java应用程序提供了与本地代码交互的能力。在Android系统中,JNI主要用来...
JNI(Java Native Interface)作为Android开发中的一个重要组成部分,它充当了Java层与C/C++层之间的桥梁。在Android双层架构中,上层为Java框架,而下层为C/C++框架。这两层之间需要频繁交互数据和调用函数,这时就...
在Android开发中,有时我们需要处理复杂的数学计算,例如解析和计算数学表达式。为了提高性能,我们可以使用Native Development Kit (NDK) 和Java Native Interface (JNI) 来实现。本教程将详细介绍如何通过NDK和JNI...
### Android NDK 开发教程之 Hello JNI 示例详解 #### 一、引言 在移动应用开发领域,Android NDK (Native Development Kit) 提供了一种使用 C 或 C++ 编写原生代码的方式,这对于提高应用程序性能至关重要。本文...