一、JNI (Java Native Interface)
JNI是Java提供的与系统Native库交互的一种机制。
Java代码运行在JVM中,JVM可以跟操作系统来调用系统的Native动态链接库。
这些动态链接库由C/C++源代码来编译生成,在不同操作系统中格式不同,例如在linux平台下会编译为.so或.a文件,在window平台下会编译为dll文件,在mac os下会编译为jnilib。
Android是基于Linux的,所以在Android平台上JNI调用的动态连接库是.so文件。
从效果上讲,把JNI理解成通过Java来与C/C++代码交互的机制也可以。(实际是与这些C/C++编译成的动态链接库交互。)
参考剪藏:详解JNI到底是什么
二、NDK (Native Development Kit)
NDK是Android提供的一个开发工具包,主要是方便开发者将C/C++代码编译成Android中的动态链接库(.so)。
这样开发者就可以用Java代码通过JNI方式来调用这些.so库中的方法。
之所以不完全用Java代码,而是要把部分功能封装在.so中,原因主要是:
1.部分功能需要较高的执行效率,这方面java远不如C/C++;
2.出于安全考虑,java代码较容易被反编译,而C/C++编译成的动态链接库(.so库)反编译难度很大。
一些关键而机密的信息,例如一些ID值,应该存放在.so库中。
&&.a库和.so库的区别:
Linux下的链接库分两种,.a静态链接库和.so动态链接库。同样的源代码,一般打出的静态库体积较大。
1.a静态库在编译时就会被连接到目标代码,最终会被整合到目标代码中输出。
静态库只能被native层调用,在NDK开发中,一般用于支持别的静态库或动态库打包。
2.so动态库在编译时不会被连接到目标代码,而是运行时才会在.so中找目标方法来执行。
动态库可被natvie层调用,java层通过JNI方式也可调用。很显然,我们一般需要打的是能供java层调用的.so动态库。
参考剪藏:Android NDK 简介 - JNI/NDK 开发指南 - UDN开源文档
三、JNI、NDK在AndroidStudio下的简单使用示例
现在Android官方文档主要讲得都是如何用CMake方式来进行NDK编译,感觉这是官方所提倡的方式。
而且CMake的编译脚本是跨平台的,所以我们这里用CMake的方式来演示一个简单的.so包的编译。
1.前期准备工作
1.1首先要在AndroidStudio的SDKManager中下载NDK和CM