1、JNI简介
1.1、JNI是Java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++代码也可以调用Java代码。1.2、JNI是Java和C/C++相互交流的接口
1.3、JNI的能够让Java调用底层的C/C++代码,是因为C/C++的高效性,但是放弃了Java的跨平台性
2、JNI与NDK
2.1、JNI是在传统的Java程序中就存在了的,而NDK是现在Android专有的,可以说NDK是一种特殊的JNI2.2、JNI调用有以下步骤:
(1)编写包含native本地方法的Java类
(2)通过javah工具生成C/C++语言的头文件,使用C/C++语言实现头文件
(3)使用交叉编译工具对C/C++代码进行本地代码编译,生成库文件
(4)在java中调用库文件中已经实现的本地方法
2.3、在Android NDK的早期版本,需要使用交叉编译工具Cygwin,R7之后可以直接使用Google提供的脚本ndk-build.cmd(针对的windows平台)
3、使用环境
3.1 使用到了底层的驱动模块,需要借助于C接口,Java本身是不能调用底层代码的3.2 虽然Java也很高效,但是如果有大量的数据处理模块,C的效率要远远高于Java
3.3 一些需要封装的协议等,C的发展历程较Java更为久远,更加成熟,有很多可以复用,且破解难度高
4、参数列表
4.1 JNIEnv对象是当前的JVM运行环境,相当于JVM的“管家”,可以通过它方位JVM内部的各种对象。4.2 jobject是调用该函数的对象,一般就是java当前的这个类对象。
4.3 如果函数还有其它参数,那么需要将参数放在上面两个参数的后面
// stringToJni对应在Java中的声明
private native String stringFromJni();
// stringToJni对应在JNI中的声明
JNIEXPORT jstring JNICALL stringFromJni(JNIEnv *env, jobject clazz);
// stringToJni对应在Java中的声明
private native void stringToJni(String val);
// stringToJni对应在JNI中的声明
JNIEXPORT void JNICALL stringToJni(JNIEnv *env, jobject clazz, jstring val);
5、如何使用
JNI编写的C语言代码如下:
#include <string.h>
#include <jni.h>
// 这里表示返回的是字符串类型
jstring
// Java中的包名/Java中的类名/Java调用的方法名/参数列表
Java_com_example_testjni_MainActivity_stringFromJNI( JNIEnv* env,
jobject thiz ){
// 下面是一段比较简洁的,对自身系统判断,出于哪一种架构模式
// 主要有x86和arm架构
#if defined(__arm__)
#if defined(__ARM_ARCH_7A__)
#if defined(__ARM_NEON__)
#define ABI "armeabi-v7a/NEON"
#else
#define ABI "armeabi-v7a"
#endif
#else
#define ABI "armeabi"
#endif
#elif defined(__i386__)
#define ABI "x86"
#elif defined(__mips__)
#define ABI "mips"
#else
#define ABI "unknown"
#endif
// 返回一个字符串
return (*env)->NewStringUTF(env, "Hello from JNI ! Compiled with ABI " ABI ".");
}
对应的JAVA代码如下所示:
public class MainActivity extends ActionBarActivity {
static {
System.loadLibrary("hello-jni");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.activity_main);
TextView tv = new TextView(this);
tv.setText( stringFromJNI() );
setContentView(tv);
}
public native String stringFromJNI();
public native String unimplementedStringFromJNI();
}