链接:https://pan.baidu.com/s/1zB9r5WwuTMIPNMlYl5HlvA
提取码:5ndl
本篇以下篇的代码为例,实现在JNI函数里更新java层的数组,没有看过下篇的朋友,可以先去看下。
Android JNI学习04-AndroidStudio3.6 java 向 C++函数传递数组
在MainActivity中调用sendIntArrayToJNI
sendIntArrayToJNI对应的JNI函数内容如下
extern "C"
JNIEXPORT jstring JNICALL
Java_com_example_jnistudy_MainActivity_sendIntArrayToJNI(JNIEnv *env, jobject thiz,
jintArray int_array) {
jint *javaArray = env->GetIntArrayElements(int_array, NULL);
int32_t length = env->GetArrayLength(int_array);
for (int k = 0; k < length; ++k) {
int tmp = *(javaArray+k);
__android_log_print(ANDROID_LOG_ERROR,"JNI","数组的值:%d",tmp);
*(javaArray+k) = tmp+10;
}
std::string hello = "测试数组传递";
return env->NewStringUTF(hello.c_str());
}
以上 的代码仅仅是对数组的内容进行输出。
修改一个数组很简单,只需要通过指针,很容易做到,代码如下
可以看到,只需要增加红框部分就可以做到修改数组。
那么我们先运行看一下,看是否java层的数组,数据是否改变。
为了便于观察,在java层将数组打印出来
现在就开始运行
你会发现一个奇怪的现象,我不是在JNI层修改了吗?为什么还是没有改变。
原因是这样的,
*(javaArray+k)指向的数组地址,和 java层所在的数组地址并不是同一个,*(javaArrray+k)里保存的数据,仅仅是java层数组的一个备份而已。所以无论你怎么改,肯定是影响不了java层的数组的。那我非要通过JNI函数改变java层的数组,要如何做呢?可以通过如下方式。
你只需要通过ReleaseIntArrayElements这个函数,就可以做到将JNI层的更改,影响到java层。这个函数内部其实就是,将JNI层做的更改,再次拷贝到Java层的数组里。
ReleaseIntArrayElements的最后一个参数是工作模式,有三种
0: 刷新java数组 并 释放c/c++数组
1 = JNI_COMMIT:
只刷新java数组
2 = JNI_ABORT
只释放
我们这里选择的是0,它会释放JNI层的备份数组,同时会将JNI层对数组做的更改,进行同步。
明白了这点之后,现在就来运行下吧
可以发现,数据确实更改了。
Android JNI学习07-AndroidStudio3.6 JNI函数调用java层实体类get,set 和 静态方法,以及获取和修改成员属性