鏈接: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 和 靜態方法,以及獲取和修改成員屬性