Android C++ 系列:认识 JNI
1. 什么是 JNI
JNI 是 Java Native Interface 的缩写,通过使用 Java 本地接口书写程序,可以确保代码在不同的平台上方便移植。
JNI 不仅仅是 Android 特有的,它是属于 Java 平台的,它允许在 Java 虚拟机内运行的 java 代码与其他编程语言(如 c, c++和汇编语言)编写的程序和库进行交互。Java1.1 开始,JNI 标准成为 java 平台的一部分,它允许 Java 代码和其他语言写的代码进行交互。JNI 一开始是为了本地已编译语言,尤其是 C 和 C++而设计的,但是并不是说不能使用其他编程语言,只要调用约定受支持就可以了。不同语言编写的程序之间调用也不是 Java 和 C++特有的,Java 可以调用 C++,python、go 语言都可以。
JNI 使得在 Java 虚拟机内运行的 Java 代码能够与其它编程语言互相操作,包括创建本地方法、更新 Java 对象、调用 Java 方法,引用 Java 类,捕捉和抛出异常等,也允许 Java 代码调用 C/C++或汇编语言编写的程序和库。作为一个标准程序接口,它没有对底层 Java 虚拟机的实现施加任何限制,并具有以下特点:
二进制兼容。本地方法库与同一平台上所有 Java 虚拟机之间实现二进制兼容,即对于给定平台开发人员只需要维护一种版本的本地方法库。但是同时也丧失了跨平台性,想想我们 Android 只编译 arm 平台的 so 库,就会导致无法在 x86 平台运行。
效率高。为了实现实时系统,JNI 在效率与虚拟机无关性之间进行了优化,以保障高效运行。
功能强。JNI 提供了大量的函数及接口让本地方法与 Java 虚拟机内核相互操作,增强两者的功能。
2. 为什么会有 JNI
JNI 产生的原因和背景是什么呢?我们熟练掌握一门语言后为什么还要再用另一门语言去写呢?它是出于以下几方面的考虑:
历史程序复用:很多已经使用其他语言实现的功能,我们可以直接拿来主义,编译完直接使用,比如音视频领域强大的 ffmpeg 就是用纯 c 语言实现的,如果再用 java 实现一遍就是完全重复造轮子;
跨平台代码复用:我们想写一份代码 Android、iOS、Mac、Linux 公用,他们不同平台使用不同语言,怎么办呢?使用 C/C++实现核心功能,然后不同平台使用不同语言的本地接口进行调用;
弥补 Java 平台无关性的不足:Java 平台无关性导致访问系统底层或者驱动方面存在缺陷,因为我们知道操作系统都是 C/C++实现,如果要访问底层硬件能力,必须要能调用 C/C++接口。在 Android 中,我们的摄像头、麦克风、显示屏、硬件编解码器等能力在底层都是由 C/C++封装;
性能考虑:有些 CPU 密集型操作可以使用 JNI 调用 C/C++或者汇编实现,来提高效率。
3. JNI 接口介绍
JNI 对外暴露的接口主要是我们jni.h
头文件,头文件里面为我们封装了 JNIEnv 环境变量结构和 JavaVM 结构体。任何方法的调用都离不开 JNIEnv 变量,C 和 C++接口还有一些差异:在 C 的定义中,env 是一个两级指针,而在 C++的定义中,env 是个一级指针。C 形式需要对 env 指针进行双重 deferencing,而且须将 env 作为第一个参数传给 jni 函数,举个简单的例子:
对于 demo.c:JNI 函数调用由
(*env)->
作前缀,目的是为了取出函数指针所引用的值,如:return (*env)->NewStringUTF(env,"HelloJNI!");
对于 demo.cpp:JNIEnv 类拥有处理函数指针查找的内联成员函数,如:
return env->NewStringUTF("HelloJNI!");
但是其实本质没有什么区别,一个是 JNI 调 C,一个是 JNI 调 C,C 再调 C++。
4. 经常与我们打交道的 JNI
下面介绍下我们日常接触的一些使用了 JNI 能力的开源库:
ijkplayer:做移动端播放器的对 ijkplayer 不会陌生,它是哔哩哔哩推出的跨平台开源播放器,由于它底层是 ffmpeg 实现,用到了 C 代码,所以需要通过 JNI 做包装;
webrtc:谷歌开源的跨平台实时通信库,包括 3A,弱网对抗等核心能力使用 C/C++实现,平台层做少量包装适配;
mars:微信开源的一个跨平台长连接信令库,里面还有一个高性能日志库,核心代码用 C/C++实现,然后在上层不同平台做少量适配;
tenforflow lite:机器学习库,C 语言实现,可以一份代码编译成不同平台库。
5. 总结
本介绍了 JNI 概念以及 JNI 的作用、JNI 提供的接口,以及我们常用到的一些使用了 JNI 的开源程序。
版权声明: 本文为 InfoQ 作者【轻口味】的原创文章。
原文链接:【http://xie.infoq.cn/article/f01c1f1071e66d0cd3f97bed4】。文章转载请联系作者。
评论