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++程序集成到一起。

版权归他们:《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系统的图像处理再多说一句,运行时间长的操作尽量都放在服务器端,否则用户会崩溃的。


目录
相关文章
|
7月前
|
安全 Android开发
[笔记]安卓逆向之动态调试
[笔记]安卓逆向之动态调试
|
9月前
|
Android开发 Windows
Android逆向 | 基础知识篇 - 02 - 关于Android签名
Android逆向 | 基础知识篇 - 02 - 关于Android签名
|
9月前
|
缓存 算法 安全
Android逆向 | 基础知识篇 - 01
Android逆向 | 基础知识篇 - 01
202 0
|
12月前
|
JavaScript 前端开发 安全
开心档-Kotlin 教程
【摘要】 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,被称之为 Android 世界的Swift,由 JetBrains 设计开发并开源。 Kotlin 可以编译成Java字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。 在Google I/O 2017中,Google 宣布 Kotlin 成为 Android 官方开发语言。
|
Java 编译器 C语言
NDK | C++ 复习笔记
NDK | C++ 复习笔记
80 0
|
存储 缓存 Java
NDK | C 语言复习笔记
NDK | C 语言复习笔记
62 0
NDK | C 语言复习笔记
手把手教学APK反编译实现源码阅读
我们编写源程序经过编译变成可执行文件,反编译就是其逆过程。 为什么要需要研究反编译? 在小公司开发中,偶尔就只有1-2个人独立面对一个项目。碰到问题后,可能你身边没有什么技术大牛,这时运用反编译,可以研究一个实现类似功能程序的源代码,吸取别人的编程思路和经验,提高自己的编程能力 。 这边特别声明,告诉你这个方法纯粹是为了学习编程技术,而不是教你盗版别人的软件。
163 0
手把手教学APK反编译实现源码阅读
|
Web App开发 机器学习/深度学习 JavaScript
WebAR入坑学习
WebAR入坑学习
865 0
WebAR入坑学习
|
测试技术 Java 开发工具
BAT程序员们常用的开发神器(附代码、教程)
工欲善其事必先利其器,善于利用各种开发工具同样可以事半功倍。
5320 0
|
机器学习/深度学习 算法 Java
【干货推荐】Android开发该学习哪些东西?
开篇: 本人也是众多Android开发道路上行走的一员,听了不少大神的知乎live,自己也看了不少书,也和不少前辈交流过,所以在这里分享一下Android开发应该学习的书籍以及知识,当然,也包括一些方法,希望对更多想进入这个行业的人有所帮助。