NDK抄书笔记【枯燥】
版权归他们:《Android高级开发实战---UI、NDK与安全》 王氏兄弟
1.何为JNI
JNI (Java Native Interface) 即Java本地开发接口,也是C/C++与Java通信的一个协议,这个协议可以使Java代码与C/C++代码之间进行沟通,通过该协议,Java代码就可以调用C/C++代码,C/C++代码也可以调用Java代码,这样就可以将Java程序与C/C++程序集成到一起。
2.为什么要用JNI
a. JNI扩张了Java虚拟机的能力。Java语言是不能够直接操作硬件的(Java在实现跨平台操作时,将硬件操作全部封装起来)。例如,Java语言是不能够直接用来开发驱动的,但Java可以通过JNI来做一些驱动开发(驱动开发需要操作硬件,而C语言可以实现对硬件的操作,Java通过JNI协议,可以实现对C的调用)
b. C/C++语言的运行效率高(Java的执行效率相对低一点,魔乐科技的李兴华说:java实在c++的基础上改写而来,C#是由java和c++改写而来),应用比较广泛例如,数学运算、实时渲染Opengl、音/视频处理ffmpeg
c. 直接复用C/C++中的优秀代码(文件压缩、人脸识别)
d. Java不可以手动释放内存,而C/C++可以实现手动控制内存,如果对内存的利用有较高要求时,需要使用C/C++来实现。
e.特殊的业务场景,如高级汽车上安装的车载电脑的onboard debug system,需要获取硬件的电信号
3.如何使用JNI
NDK,Natvie Develop Kits,·可以将C/C++语言写出来的源代码编译成可执行的文件(文件格式以.so为 扩展名,该文件组成的库称之为“可执行动态库”)。
Java端需要有JVM和Class类(得到Class对象后,就可以调用该Class中的方法);C/C++端需要有function函数与function.lib函数库。C/C++的函数通过JNI机制去调用Java端的Class方法;Java端通过JNI机制去调用C/C++端的函数或者函数库。JNI在此充当C/C++与Java通信的桥梁。
Java源码经过被编译后生成了.class文件(Java字节码),通过类加载器将字节码加载到Java类库中,然后再JVM中对字节码进行解释 、翻译后才可以被计算机所识别出来;而C/C++经过编译后,生成了一个.exe文件,没有Java中将数据装载到虚拟机中进行解释、翻译这一步,两者从编译到运行的基本过程比较:C/C++-->(*.exe)-->机器,Java-->(*.class)-->JVM-->机器,这是 C/C++的运行效率高于Java的原因。
4.NDK与JNI的关系
Java通过JNI机制和C/C++沟通的具体步骤:
a.编写包含native本地方法的Java类
b.通过javah工具生成C/C++语言的头文件
c.使用C/C++语言实现头文件
d.使用交叉编译工具对C/C++本地代码进行编译,最后通过链接生成*.so可执行的C/C++库
e.实际执行Java代码去和本地的C/C++代码相互沟通
5.JNI中的Java VM与JNIEnv对象
在标准的Java平台下,每一个进程里可以产生很多Java VM对象,每一个Java VM对象都有一个与之对应的Java VM对象,但是在Android平台上,每一个进程只能产生一个Dalvik VM对象,也就是说一个Android的进程中是通过有且只有一个虚拟器对象来服务所有的Java和C/C++代码
Android中的JNIEnv对象与Dalvik的Java VM具体关系:
a. JNIEnv *内部包含一个指针,指针指向Dalvik的Java VM对象的Function Table,JNIEnv *关于程序执行环境众多函数正式来源于Dalvik虚拟机
b.Android中每当一个Java线程第一次要调用本地C/C++代码时,Dalvik虚拟机实例会为该Java线程产生一个JNIEnv*指针
c.Java每条线程在和C/C++相互调用时的JNIEnv*是相互独立的,互不干扰,这就提升了并发执行时的安全性
d.当本地的C/C++代码想获得当前线程所要使用的JNIEnv时可以使用Dalvik VM对象的Java VM* jvm->GetEnv()方法,该方法即会返回当前线程所在的JNIEnv *
6.Java、Dalvik VM、C/C++的运行机制与流程
a.Java的dex字节码和C/C++的*.so同时运行Dalvik VM之内,共同使用一个进程空间。
b.Java和C/C++可以相互调用,其调用的关键均是Dalvik VM
c.一般而言,比较经典的模式是Java通过JNI的C组件和C++相互沟通,一般的业务处理代码是放在C++中的
d.C++代码处于核心的控制地位具有更高的价值
当Java代码需要C/C++代码时,在Dalvik虚拟机加载进*.so库时,会先调用JNI_OnLoad()函数,此时就会把Java VM对象的指针存储于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层代码。
关于android系统的图像处理再多说一句,运行时间长的操作尽量都放在服务器端,否则用户会崩溃的。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
关于微博认证和微信认证
微博认证需要有已经认证的新浪微博或者腾讯微博账号,需要粉丝为500人以上,认证后账号将显示微博认证。认证以后功能上和没有认证并没有什么区别,但搜索的时候可以排名靠前。微信认证起初只有部分合作账号有,比如:深圳东部华侨城。2013年10月29日,微信官方开放微信认证,需要300元费用,通过之后,拥有一年的高级接口功能。- 语音识别- 客服接口- 修改 OAuth2.0网页授权- 生成带参数二维码- 关闭获取用户地理位置- 获取用户基本信息- 获取关注者列表- 用户分组接口- 上传下载多媒体文件
- 下一篇
Eclipse+Java+OpenCV246人脸识别
---恢复内容开始--- 1.环境搭建:见上一篇博客 整个项目的结构图: 2.编写DetectFaceDemo.java,代码如下: [java] view plain copy "> packagecom.njupt.zhb.test; importorg.opencv.core.Core; importorg.opencv.core.Mat; importorg.opencv.core.MatOfRect; importorg.opencv.core.Point; importorg.opencv.core.Rect; importorg.opencv.core.Scalar; importorg.opencv.highgui.Highgui; importorg.opencv.objdetect.CascadeClassifier; // //Detectsfacesinanimage,drawsboxesaroundthem,andwritestheresults //to"faceDetection.png". // publicclassDetectFaceDemo{ ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Red5直播服务器,属于Java语言的直播服务器
- Windows10,CentOS7,CentOS8安装Nodejs环境
- CentOS7,8上快速安装Gitea,搭建Git服务器
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- SpringBoot2全家桶,快速入门学习开发网站教程
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- SpringBoot2整合Redis,开启缓存,提高访问速度
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7