你真的了解 NDK 和 jni 的区别吗

首先咱们要知道Java是如何调用c/c++的

Markdown
Markdown

什么是JNI

java native interface(java本地接口)
ABI: application binary interface (应用程序二进制接口)java

简介

JNI是Java语言提供的Java和C/C++相互沟通的机制,Java能够经过JNI调用本地的C/C++代码,本地的C/C++的代码也能够调用java代码。JNI 是本地编程接口,Java和C/C++互相经过的接口。Java经过C/C++使用本地的代码的一个关键性缘由在于C/C++代码的高效性。android

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

#为何要使用JNI程序员

  • 复用不少优秀的c/c++代码
    • ffmpeg 多媒体播放器
    • opencv 图形识别引擎
    • 7-zip 压缩
    • opencore 视频播放
  • 效率问题
    • java代码跨平台,不直接操做硬件,虚拟机解释执行。垃圾回收机制。
    • art 在安装apk应用程序的时候,把apk里面的dex翻译成机器码(apk的体积会变大)
    • c代码直接操做硬件,程序员能够手工的释放内存
  • 应用场景问题
    • c代码能够直接操做硬件。
    • java代码只能操做虚拟机(一次编译处处执行)
    • 智能家居操做硬件
    • 车载电脑(obd: onboard debug system)
  • 特殊业务逻辑
    • c代码反编译困难,调试困难。
    • java代码反编译容易,很容易看懂。

#怎么使用JNI算法

  • 看懂c代码( 有c语言基础)
  • 懂流程 (熟悉jni的规范)
  • 熟练(NDK 工具 native develop kits)

开发工具

dev-cpp.exe 编程

  1. 轻量级开发工具
  2. 编译器gcc c99标准

Java经过JNI机制和C/C++沟通的具体步骤微信

  • 一、编写包含native本地方法的java类
  • 二、经过javah工具生成C/C++语言的头文件
  • 三、使用C/C++语言实现头文件
  • 四、使用交叉编译工具对C/C++本地代码进行编译
  • 五、最后经过连接生成*.so可执行的C/C++库

实际执行Java代码去和本地的C/C++代码互相沟通app

JNI中的JavaVM与JNIEnv对象

在标准的Java平台下,每一个Process里能够产生不少JavaVM对象,每一个JavaVM对象都有一个与之对应的JavaVM对象,可是在Android平台上,每一个Process只能产生一个DalvikVM对象,也就是说在一个Android的进程中是经过有且只有一个虚拟器对象来服务全部Java和C++代码的。jvm

  • 一、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*
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层代码。

NDK和jni的区别

对于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提供的库和函数功能颇有限,仅仅处理些算法效率敏感的问题

    Markdown
    Markdown

相信本身,没有作不到的,只有想不到的

若是你以为此文对您有所帮助,欢迎入群 QQ交流群 :232203809
微信公众号:终端研发部

技术+职场
技术+职场
相关文章
相关标签/搜索