注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

亲民博客

记录生活中的点点滴滴

 
 
 

日志

 
 

JNI和NDK的关系  

2014-12-17 16:59:00|  分类: 安卓开发 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
1、简介

1.1、JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性。

1.2、NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。它集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。

2、Java通过JNI机制和C/C++沟通的具体步骤
  • 编写包含native本地方法的java类
  • 通过javah工具生成C/C++语言的头文件
  • 使用C/C++语言实现头文件
  • 使用交叉编译工具对C/C++本地代码进行编译,最后通过链接生成*.so可执行的C/C++库
  • 实际执行Java代码去和本地的C/C++代码互相沟通

3、JNI中的JavaVM与JNIEnv对象


在标准的Java平台下,每个Process里可以产生很多JavaVM对象,每个JavaVM对象都有一个与之对应的JavaVM对象,但是在Android平台上,每个Process只能产生一个DalvikVM对象,也就是说在一个Android的进程中是通过有且只有一个虚拟器对象来服务所有Java和C++代码的。
  • JNIEnv *内部包含一个Pointer,Pointer指向Dalvik的JavaVM对象的Fanction Table,JNIEnv *关于程序执行环境的众多函数正是来源于Dalvik虚拟机
  • Android中每当一个Java线程第一次要调用本地C/C++代码时,Dalvik虚拟机实例会为该Java线程产生一个JNIEnv *指针
  • Java每条线程在和C/C++互相调用时,JNIEnv*是相互独立的,互不干扰
  • 每本地的C/C++代码想获得当前线程所要使用的JNIEnv时,可以使用Dalvik VM对象的Java VM* jvm->getEnv()方法,该方法即会返回当前线程所在的JNIEnv*

4、Java、Dalvik VM、C/C++的运行机制与流程

  • 在Android的NDK中,Java、C/C++、Dalvik VM关系如下:
  • java的dex字节码和C/C++的*.so同时运行DalvikVM之内,共同使用一个进程空间。每次使用jni调用c/c++开辟一个线程去处理
  • java和C/C++可以相互调用,调用的关键是DalvikVM
  • 一般而言,比较经典的模式是Java通过JNI的C组建和C++相互沟通,一般业务处理放在C/C++中
  • 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层代码。

5、总结


对于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就是简化了这个过程。

http://blog.csdn.net/banketree/article/details/12167145
  评论这张
 
阅读(4)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018