NDK 与 JNI 的关系
简介
JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性。
NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。它集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
Java通过JNI机制和C/C++沟通的具体步骤
1、编写包含native本地方法的java类
2、通过javah工具生成C/C++语言的头文件
3、使用C/C++语言实现头文件
4、使用交叉编译工具对C/C++本地代码进行编译,最后通过链接生成*.so可执行的C/C++库
5、实际执行Java代码去和本地的C/C++代码互相沟通
JNI中的JavaVM与JNIEnv对象
在标准的Java平台下,每个Process里可以产生很多JavaVM对象,每个JavaVM对象都有一个与之对应的JavaVM对象,但是在Android平台上,每个Process只能产生一个DalvikVM对象,也就是说在一个Android的进程中是通过有且只有一个虚拟器对象来服务所有Java和C++代码的。
1、JNIEnv *内部包含一个Pointer,Pointer指向Dalvik的JavaVM对象的Fanction Table,JNIEnv *关于程序执行环境的众多函数正是来源于Dalvik虚拟机
2、Android中每当一个Java线程第一次要调用本地C/C++代码时,Dalvik虚拟机实例会为该Java线程产生一个JNIEnv *指针
3、Java每条线程在和C/C++互相调用时,JNIEnv*是相互独立的,互不干扰
4、每本地的C/C++代码想获得当前线程所要使用的JNIEnv时,可以使用Dalvik VM对象的Java VM* jvm->getEnv()方法,该方法即会返回当前线程所在的JNIEnv*
Java、Dalvik VM、C/C++的运行机制与流程
在Android的NDK中,Java、C/C++、Dalvik VM关系如下:
1、java的dex字节码和C/C++的*.so同时运行DalvikVM之内,共同使用一个进程空间。每次使用jni调用c/c++开辟一个线程去处理
2、java和C/C++可以相互调用,调用的关键是DalvikVM
3、一般而言,比较经典的模式是Java通过JNI的C组建和C++相互沟通,一般业务处理放在C/C++中
4、C++代码处于核心控制地位更具价值
当java需要C/C++代码时,在DalvikVM虚拟机中加载动态链接库时,会先调用JNI_Onload()函数,此时就会把javaVM对象的指针存储于C层JNI组建的全局环境中,在JAVA层调用C层的本地库函数时,调用C本地函数线程必然通过Dalvik VM来调用C本地函数,测试Dalvik虚拟机会为本地的C组建实例化一个JNIEnv指针,该指针指向Dalvik虚拟机的具体函数列表,当JNI的C组件调用java层方法和属性时,需要通过JNIEnv指针来进行调用。
当C++组件主动调用Java层方法时,需要通过JNI的C组件把JNIEnv指针传递给C++组件,此后,c++组件即可通过JNIEnv指针来掌控Java层代码。
总结
对于JNI和NDK很多Android开发初学者没有搞明白这个问题,JNI是Java调用Native机制,是Java语言自己的特性全称为Java Native Interface,类似的还有微软.Net Framework上的p/invoke,可以让C#或Visual Basic.Net可以调用C/C++的API,所以说JNI和Android没有关系,在PC上开发Java的应用,如果运行在Windows平台使用JNI是是经常的,比如说读写Windows的注册表。而NDK是Google公司推出的帮助Android开发者通过C/C++本地语言编写应用的开发包,包含了C/C++的头文件、库文件、说明文档和示例代码,我们可以理解为Windows
Platform SDK一样,是纯C/C++编写的,但是Android并不支持纯C/C++编写的应用,同时NDK提供的库和函数功能很有限,仅仅处理些算法效率敏感的问题,所以Android123推荐初学者学好Java后再学习JNI。
简单点说,用C语言生成一个库文件,在java中调用这个库文件的函数。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
NDK 与 JNI 的关系的更多相关文章
- NDK、SDK以及JNI的关系
最近由于项目的需要,使用到了Android的NDK技术,对项目核心算法跨平台的移植.简答而言,就是使用C对原来的算法进行了改进,并集成到原 来的app项目里. 从前的项目一直没有使用NDK进行开发的机 ...
- Android游戏开发实践(1)之NDK与JNI开发03
Android游戏开发实践(1)之NDK与JNI开发03 前面已经分享了两篇有关Android平台NDK与JNI开发相关的内容.以下列举前面两篇的链接地址,感兴趣的可以再回顾下.那么,这篇继续这个小专 ...
- Android游戏开发实践(1)之NDK与JNI开发01
Android游戏开发实践(1)之NDK与JNI开发01 NDK是Native Developement Kit的缩写,顾名思义,NDK是Google提供的一套原生Java代码与本地C/C++代码&q ...
- Android游戏开发实践(1)之NDK与JNI开发02
Android游戏开发实践(1)之NDK与JNI开发02 承接上篇Android游戏开发实践(1)之NDK与JNI开发01分享完JNI的基础和简要开发流程之后,再来分享下在Android环境下的JNI ...
- Android游戏开发实践(1)之NDK与JNI开发04
Android游戏开发实践(1)之NDK与JNI开发04 有了前面几篇NDK与JNI开发相关基础做铺垫,再来通过代码说明下这方面具体的操作以及一些重要的细节.那么,就继续NDK与JNI的学习总结. 作 ...
- [ 转载 ] Android JNI(一)——NDK与JNI基础
Android JNI(一)——NDK与JNI基础 隔壁老李头 关注 4.4 2018.05.09 17:15* 字数 5481 阅读 11468评论 8喜欢 140 本系列文章如下: Androi ...
- Android JNI(一)——NDK与JNI基础
本系列文章如下: Android JNI(一)——NDK与JNI基础 Android JNI学习(二)——实战JNI之“hello world” Android JNI学习(三)——Java与Nati ...
- Android(安卓)开发通过NDK调用JNI,使用opencv做本地c++代码开发配置方法 边缘检测 范例代码
以前写过两个Android开发配置文档,使用NDK进行JNI开发,这样能够利用以前已经写好的C++代码. 前两篇博客地址: http://blog.csdn.net/watkinsong/articl ...
- 使用Android Studio自带的NDK编译JNI
/********************************************************************************** * 使用Android Stud ...
随机推荐
- android addCategory()等说明
一.隐式意图介绍 显式意图我们前面已经提到,形如: Intent intent = new Intent(); intent.setClass(this,Other.class);//此句表示显式意图 ...
- log4j日志记录级别是如何工作?
级别p的级别使用q,在记录日志请求时,如果p>=q启用.这条规则是log4j的核心.它假设级别是有序的.对于标准级别它们关系如下:ALL < DEBUG < INFO < WA ...
- Linux 下的一个全新的性能测量和调式诊断工具 Systemtap, 第 2 部分: DTrace
DTrace的原理本系列文章详细地介绍了一个 Linux 下的全新的调式.诊断和性能测量工具 Systemtap 和它所依赖的基础 kprobe 以及促使开发该工具的先驱 DTrace 并给出实际使用 ...
- Tomcat怎么实现异步Servlet
有时Servlet在生成响应报文前必须等待某些耗时的操作,比如在等待一个可用的JDBC连接或等待一个远程Web服务的响应.对于这种情况servlet规范中定义了异步处理方式,由于Servlet中等待阻 ...
- SpringMVC源码分析--文件上传
SpringMVC提供了文件上传的功能,接下来我们就简单了解一下SpringMVC文件上传的开发及大致过程. 首先需要在springMVC的配置文件中配置文件上传解析器 <bean id=&qu ...
- PHP学习(1)——我为什么要学PHP
PHP简介 PHP是一种服务器端的脚本语言,特别适合做web开发.高效.灵活.实用是PHP的特点.PHP最开始是Personal Home Page的缩写,后来正式更名为了"PHP:Hype ...
- JBOSS EAP 6 系列五 Managed domains 管理域最主要的功能是“统一部署,统一配置”
摘要 本文首先介绍Managed Domain的概念,管理域最主要的功能是"统一部署,统一配置".接下来通过一个实例在"统一配置"部分实现一个双机配置起来的域, ...
- Java 中的日期与时间
Java 日期时间 标签 : Java基础 Date java.util.Date对象表示一个精确到毫秒的瞬间; 但由于Date从JDK1.0起就开始存在了,历史悠久,而且功能强大(既包含日期,也包含 ...
- socket系列之客户端socket——Socket类
假设TCP套接字服务器端已经建立好并正在监听客户端的连接了,那么客户端就可以通过Socket类来发起连接.客户端发起一个连接请求后,就被动地在等待服务器的响应.这个类同样位于java.net包中,包含 ...
- 最简单的视频编码器:基于libx264(编码YUV为H.264)
===================================================== 最简单的视频编码器系列文章列表: 最简单的视频编码器:编译 最简单的视频编码器:基于libx ...