近些日子想整理一下知识脉络,索性就从JNI开始,开发android开发程序员或多或少会接触jni这一概念,刚刚接触这个东西只知道通过他可以让android程序调用c代码,其他的就不知道了,后来经过长时间的摸爬滚打,终于大概知道JNI到底是个什么东西了。
- 学习JNI时需要了解的一些基本知识
- JNI
JNI全称Java Native Interface,他是接口也是协议,他的出现时为了满足Java与其他语言通信,JNI是java特有的产物,所以他是属于Java的而不是属于android的,只不过大多数人是通过android知道了JNI。众所周知java是一种跨平台语言,这种跨平台的是实现方式是让java运行在虚拟机上,但是这种机制无法进行一些平台相关的操作,比如与平台特有的驱动交互。而JNI的出现就有效的解决了这一问题,通过JNI可以运行本地代码(大多数是C/C++)。同时JNI也会提升程序的运行效率(Java代码运行效率比本地代码低)。但是大自然的规律告诉我们这世上没有完全十全十美的事物,JNI的出现会影响Java的跨平台性,因为用到了本地代码,所以当需要做代码移植的时候可能就需要在修改一下本地代码。但是总体来说还是利大于弊的。
- NDK
之前一直以为NDK就是JNI,这两个是一个东西。其实不然,从官网摘下这样一段描述
The Android NDK is a toolset that lets you implement parts of your app in native code, using languages such as C and C++. For certain types of apps, this can help you reuse code libraries written in those languages.
原来NDK是Android提供的工具集,他可以帮助应用程序使用本地程序部分,也就是通过他可以编译C/C++代码部分。当然NDK不会专门针对Android程序中的本地代码部分进行编译。他也可编译一个完全脱离AndroidApp的本地代码,只要你想做没什么是不可能的。
- Java代码中的native 关键字
这个关键字代表着他所修饰的方法是一个用本地语言编写的,有了这个关键词java编译器不会去检查该方法在java层是否有实现。但是他也不会去检查他在本地方法层是否有实现,所以当用该关键词修饰了一个方法时如果在没有本地方法实现的情况下调用该方法,编译是可以通过的,但是运行时就会报错。
- JNIeEnv
阅读jni.h的时候可以发现JNIEnv 是对JNINativeInterface 的封装,而JNINativeInterface 正是JNI对外开放的接口的集合,也就是说JNIEnv代表的是虚拟机的运行环境,可以通过他操作虚拟机,调用虚拟机提供的函数。这里需要提的是JNIEnv的特别之处在于他只在当前线程有效,不可以把它缓存起来再通过另一个线程操作他,那样是无效的,也是不合法的。
了解以上几个概念之后接下来就可以搬JNI牌实心砖了。