JNI是Java语言提供的Java和C/C++相互沟通的机制,Java可以通过JNI调用本地的C/C++代码,本地的C/C++的代码也可以调用java代码。JNI 是本地编程接口,Java和C/C++互相通过的接口。Java通过C/C++使用本地的代码的一个关键性原因在于C/C++代码的高效性。
NDK是一系列工具的集合。它提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java应用一起打包成apk。这些工具对开发者的帮助是巨大的。它集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。它可以自动地将so和Java应用一起打包,极大地减轻了开发人员的打包工作。
二、数组参数应用
JNI中的数组分为基本类型数组和对象数组,它们的处理方式是不一样的,基本类型数组中的所有元素都是JNI的基本数据类型,可以直接访问。而对象数组中的所有元素是一个类的实例或其它数组的引用,和字符串操作一样,不能直接访问Java传递给JNI层的数组,必须选择合适的JNI函数来访问和设置Java层的数组对象。阅读此文假设你已经了解了JNI与Java数据类型的映射关系,下面说明基本数据类型数组的访问方式
三、具体代码说明参数传入和方法签名
extern "C" jstring Java_com_aaa_app_MainActivity_ArrayOperator(JNIEnv *env, jobject obj, jobject inObject) { std::string hello = "aaa"; jclass clazz = env->GetObjectClass(inObject); //获取Java中的isConnected方法的id(最后一个参数是isConnected方法的签名) jmethodID methd = env->GetMethodID(clazz,"isConnected","()Z"); env->CallBooleanMethod(inObject, methd); methd = env->GetMethodID(clazz, "readAndWrite", "([B)[B"); jbyte nativeArr[3] = {0x03, 0x02, 0x00}; jbyteArray nativeArr1 = env->NewByteArray(3); env->SetByteArrayRegion(nativeArr1, 0, 3, nativeArr); //调用方法,这个地方很关键,数组返回值,使用的是CallObjectMethod jobject a = env->CallObjectMethod(inObject, methd, nativeArr1);
//再把返回对象,转成相应数据类型数组 jbyte* aa1 = env->GetByteArrayElements((jbyteArray)a, NULL); return env->NewStringUTF(hello.c_str()); }