前言
前面我们已经介绍了native函数访问Java的各类方法,诸如静态方法、非静态方法、结构方法,本篇博客将介绍数组的同步问题。
数组传入
创建native方法,用于将Java中的数组传入到native函数中,调用C的函数进行排序,再将排序好的数组同步到Java数组中。
public native void putArray(int[] arr);
在MainActivity的onCreate中
int[] array = {1, 20, 11, 55, 90, 100, 5, 70};
putArray(array);
//如果不加同步代码,这里打印出来的还是未排序的
for (int i = 0; i < array.length; i++) {
System.out.println("Java " + array[i]);
}
native函数的实现:
JNIEXPORT void JNICALL
Java_com_zhangpan_myjnicmake_MainActivity_putArray(JNIEnv *env, jobject jobj, jintArray arr_) {
//jintArray --> jint指针 --> C int 数组
jint *arr = (*env)->GetIntArrayElements(env, arr_, NULL);
//数组的长度
jint arrLength = (*env)->GetArrayLength(env, arr_);
//排序
qsort(arr, arrLength, sizeof(jint), commpare);
//同步
//0:Java数组进行更新,并且释放C/C++数组
//JNI_ABORT:Java数组不进行更新,但是释放C/C++数组
//JNI_COMMIT:Java数组进行更新,不释放C/C++数组(函数执行完后,数组还是会释放的)
(*env)->ReleaseIntArrayElements(env, arr_, arr, JNI_COMMIT);
}
运行打印结果:
1.png
从打印结果可以得出,这里已经将排序好的C/C++数组,同步到了Java数组中。
这里需要注意ReleaseIntArrayElements中的第四个参数:
//0:Java数组进行更新,并且释放C/C++数组
//JNI_ABORT:Java数组不进行更新,但是释放C/C++数组
//JNI_COMMIT:Java数组进行更新,不释放C/C++数组(函数执行完后,数组还是会释放的)
数组返回
定义一个native方法
public native int[] getArray(int arrLength);
在MainActivity中的onCreate方法中调用,并打印
int[] arr = getArray(5);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
native函数的实现
JNIEXPORT jintArray JNICALL
Java_com_zhangpan_myjnicmake_MainActivity_getArray(JNIEnv *env, jobject jobj, jint arrLength) {
//创建一个指定大小的数组
jintArray array = (*env)->NewIntArray(env, arrLength);
jint* elementp = (*env)->GetIntArrayElements(env, array, NULL);
jint* startP = elementp;
int i = 0;
for (; startP < elementp + arrLength; startP++) {
(*startP) = i;
i++;
}
//同步,如果没有同步Java层打印出来的数组里面的各个值为0
(*env)->ReleaseIntArrayElements(env, array, elementp, 0);
return array;
}
运行输出结果:
2.png
如果ReleaseIntArray中的第四个参数传入的是JNI_ABORT,那打印的结果全是0,因为没有进行同步,Java数组默认初始化为0。
项目地址
https://github.com/fsrmeng/MyJniCmake-Master
展望
本篇博客介绍了数组的同步问题,接下来我将介绍JNI引用相关知识,敬请期待!