背景
入职后围观mentor完成一个关于人脸识别的需求,发现mentor掏出C++开始写上层应用,大为震惊。在学校时有一个同学(擅长C和算法)曾经问老师C是否可以用来写Android,老师给与了否定的回答,懵懂的我也对此深信不疑。直至看到有人用C写上层应用,十分好奇这是如何实现的。
了解JNI之前先看看Android 技术栈的架构吧
Android 技术栈
Android 技术栈主要为四层结构/五层结构
从上至下第二层为Android framework层,主要是java代码实现的(现在或许kotlin更多?)。四层的分类方法就是把第三层的native和hal层合并到一起,划分为第三层。
从目前的技术栈分层结构来看,很明显framework层主要是java的代码,native主要是c/c++。为了避免重复造轮子同时还能使用c广阔的库,android采用了JNI技术封装c的韩函数和库,供java层使用(framework和app层)。
JNI
JNI概述
在了解JNI之前先明确一下JNI是什么:
JNI is the Java Native Interface. It defines a way for the bytecode that Android compiles from managed code (written in the Java or Kotlin programming languages) to interact with native code (written in C/C++). JNI is vendor-neutral, has support for loading code from dynamic shared libraries, and while cumbersome at times is reasonably efficient.
这一段英语,单词都认识,连起来真让人头疼。
那就翻译翻译:
JNI 是指 Java 原生接口。它定义了 Android 从受管理代码(使用 Java 或 Kotlin 编程语言编写)编译的字节码与原生代码(使用 C/C++ 编写)互动的方式。JNI 不依赖于供应商,支持从动态共享库加载代码,虽然有时较为繁琐,但效率尚可。
好像翻译成中文也不是那么好理解。
再翻译翻译:
JNI(Java Native Interface)就是Native和Java层的接口,定义了字节码和原生代码的交互方式。
好像还是不是简洁
JNI就是一个定义C/C++和Java交互的接口!
奥,原来这就是JNI,原来就是一个Java和Native接口,人如其名呐。
JNI功能
JNI在Android中能起到什么作用呢? 从mentor的代码来看,主要功能为:
- Java层调用Native(C/C++)层方法,使用native层已有的库或者方法。
例如:在人脸识别应用中,应用层捕获人脸图片,通过接口将图片传递给人脸识别相关的.so处理,接着获取处理结果,判断年龄等信息。或者MediaScanner中的processFile()等方法。AOSP中大量使用了JNI技术,通过JNI技术可以打通C和Android的屏障,使得Java也可以利用C丰富的库。
- 使得native层的函数可以调用Java层的函数。(引用自《深入理解Android 卷一》)
native引用java层函数这个特性目前我还没遇到过,但是看到邓平凡老师的《深入理解Android 卷一》中有这样的描述。在此引用一下。
简而言之,JNI是Java和Native世界沟通的桥梁,通过JNI,Java和Native可以互相调用。三者之间的关系如下: