1.1、JNI是java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI
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
-
在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++代码处于核心控制地位更具价值
当C++组件主动调用Java层方法时,需要通过JNI的C组件把JNIEnv指针传递给C++组件,此后,c++组件即可通过JNIEnv指针来掌控Java层代码。
5、总结
对于JNI和NDK很多Android开发初学者没有搞明白这个问题,JNI是Java调用Native机制,是Java语言自己的特性全称为Java
简单点说,用C语言生成一个库文件,在java中调用这个库文件的函数。JNI的过程比较复杂,生成.so需要大量操作,而NDK就是简化了这个过程。
http://blog.csdn.net/banketree/article/details/12167145