JNI
定义 :
Java Native Interface,即 Java本地接口
作用:
使得Java 与 本地其他类型语言(如C、C++)交互
注意:
JNI是Java调用Native语言的一种特性JNI是属于Java的,与Android无直接关系
调用实现步骤:
- 在
Java中声明Native方法(即需要调用的本地方法) - 编译上述
Java源文件javac(得到.class文件) - 通过
javah命令导出JNI的头文件(.h文件) 使用
Java需要交互的本地代码 实现在Java中声明的Native方法如
Java需要与C++交互,那么就用C++实现Java的Native方法编译
.so库文件- 通过
Java命令执行Java程序,最终实现Java调用本地代码
NDK
定义 :
Native Development Kit,是 Android的一个工具开发包
NDK是属于Android的,与Java并无直接关系
作用:
快速开发
C、 C++的动态库,并自动将so和应用一起打包成APK(即可通过NDK在Android中 使用JNI与本地代码(如C、C++)交互。)NDK集成了交叉编译器,并提供了相应的mk文件隔离平台、CPU、API等差异,开发人员只需要简单修改.mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。NDK提供了一份稳定、功能有限的API头文件声明。
调用实现步骤:
配置
Android NDK环境创建
Android项目,并与NDK进行关联在
Android项目中声明所需要调用的Native方法使用
Android需要交互的本地代码 实现在Android中声明的Native方法 。
比如Android需要与C++交互,那么就用C++实现Java的Native方法通过
ndk - bulid命令编译产生.so库文件编译
Android工程,从而实现Android调用本地代码
Android工程中C/C++代码解析
native-lib.cpp
#include <jni.h>
#include <string>
extern "C"
JNIEXPORT jstring JNICALL
Java_com_kevin_cpp_MainActivity_stringFromJNI(
JNIEnv *env,jobject obj ) {
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
JNIEXPORT、NICALL、JNIEnv和jobject都是JNI标准中所定义的类型或者宏,它们的含义如下:JNIEXPORT和JNICALL:他们是JNI中所定义的宏,可以在jni.h这个头文件中查询到;JNIEnv*:表示一个指向JNI环境的指针,可以通过它来访问JNI提供的接口方法。jobject:表示Java对象中的this;
注意:JNI调用C或者C++存在区别:
JNI是由C语言定义接口的,JNI通过函数名找函数入口,执行函数里的内容。这和函数用什么语言生成的并没有关系。只要保证函数名称符合JNI的协议。而使用C++要注意的是C++默认生成的函数名称和你写在源文件中的名称并不相同,因为C++要处理函数重载,会在函数名称中加上参数信息,这称为name mangling。
解决方法是定义函数时在前面加上extern"C"修饰,告诉编译器这函数按照C语言方式编译和链接。extern"C"这个声明的真实目的是为了实现C++与C及其它语言的混合编程。在
C的定义中,env是一个两级指针,而在C++的定义中,env是个一级指针
C形式需要对env指针进行双重deferencing,而且须将env作为第一个参数传给jni函数。
在C代码中:JNI 函数调用由“(*env)->”作前缀,目的是为了取出函数指针所引用的值。
return (*env)->NewStringUTF(env,"HelloJNI!");
在C++代码中:JNIEnv 类拥有处理函数指针查找的内联成员函数。
return env->NewStringUTF("HelloJNI!");
可以发现,C或者C++的实现很类似,但是它们对env的操作方式不同,因此使用C和C++来实现同一个JNI方法,它们的区别主要集中在对env的操作上。
本文详细介绍了Java Native Interface (JNI) 和 Android NDK 的概念、作用及调用步骤。对比了JNI与NDK的不同之处,并提供了C/C++代码示例说明如何在Android环境中使用JNI与本地代码交互。
533

被折叠的 条评论
为什么被折叠?



