前言
上一篇《》介绍的是jintArray的使用,今天就介绍对象数组。
- jarray (数组)
- jobjectArray (object数组)
- jbooleanArray (boolean数组)
- jbyteArray (byte数组)
- jshortArray (short数组)
- jintArray (int数组)
- jlongArray (long数组)
- jfloatArray (float数组)
- jdoubleArray (double数组)
其实数组的使用都差不多,但jobjectArray看起来较特殊,就单独拎出来。
正文
这里以Integer[]为例哈,顺带复现一下《》的使用。
Signature(签名)
- #java
- #签名:([Ljava/lang/Integer;)[Ljava/lang/Integer;
- public static native Integer[] native_sortInteger(Integer[] buffer);
如何还对Signature(签名)获取不太理解,推荐在看看《》。这里还是在之前《》基础修改。
- /**
- * 定义Java和JNI函数的绑定表
- * 方法数组,分别为:(native方法 , 方法签名 , 函数指针[JNI中需要实现的方法名])
- * 通过javac和javap 获取 方法签名
- */
- JNINativeMethod method_table[] = {
- {"native_sortInteger", "([Ljava/lang/Integer;)[Ljava/lang/Integer;", (void *) native_sort_integer},
- };
涉及函数
- # 查找class引用
- jclass (*FindClass)(JNIEnv*, const char*);
- # 获取方法ID
- jmethodID (*GetMethodID)(JNIEnv*, jclass, const char*, const char*);
- # 同方法ID调用java方法
- jint (*CallIntMethod)(JNIEnv*, jobject, jmethodID, ...);
- # 获取域(变量)ID
- jfieldID (*GetFieldID)(JNIEnv*, jclass, const char*, const char*);
- # 获取域ID对应的值
- jint (*GetIntField)(JNIEnv*, jobject, jfieldID);
- # 改变域ID对应的值
- void (*SetIntField)(JNIEnv*, jobject, jfieldID, jint);
- # 获取数组长度
- jsize (*GetArrayLength)(JNIEnv*, jarray);
- # 获取指定位置的对jobject
- jobject (*GetObjectArrayElement)(JNIEnv*, jobjectArray, jsize);
- # 改变指定位置的jobject
- void (*SetObjectArrayElement)(JNIEnv*, jobjectArray, jsize, jobject);
代码片段
下面是native_sort_integer的实现代码。
看起来有点复杂,其实就是两个功能
计算数组中的sum
排序
由于这里用的是Integer对象,因此需要find到Integer的类引用,有两种方式获取Integer中的值,一个是通域ID(属性ID)value,另外一个是通过方法ID。
- JNIEXPORT jobjectArray
- JNICALL native_sort_integer(JNIEnv *env , jclass clazz, jobjectArray integerArray){
- jclass integerClass = env->FindClass("java/lang/Integer");
- if( NULL == integerClass ){
- LOGE("native_printf_integer integerClass(NULL)");
- return NULL;
- }
- //intValue是Java中Integer的方法
- jmethodID intValueMethodID = env->GetMethodID(integerClass, "intValue", "()I");
- if( NULL == intValueMethodID ){
- LOGE("native_printf_integer intValue(NULL)");
- return NULL;
- }
- //value通过Integer的变量
- jfieldID valueFieldID = env->GetFieldID(integerClass, "value", "I");
- if( NULL == valueFieldID ){
- LOGE("native_printf_integer valueFieldID(NULL)");
- return NULL;
- }
- //获取integerArray长度
- jsize length = env->GetArrayLength(integerArray);
- LOGE("native_printf_integer length(%d)", length);
- if (length <= 0) {
- return NULL;
- }
- int i = 0;
- int sum = 0;
- jint array[length];
- for (i = 0; i < length; i++) {
- jobject object = env->GetObjectArrayElement(integerArray, i);
- if( NULL != object){
- // 1. value值通过jmethodID获取[这里注释掉了]
- //sum += env->CallIntMethod(object, intValueMethodID);
- // 2. value值通过jfieldID直接获取
- jint value = env->GetIntField(object, valueFieldID);
- sum += value;
- array[i] = value;
- }
- }
- //打印SUM值
- LOGE("native_printf_integer sum(%d)", sum);
- //从大到小排序
- int j = 0;
- int temp = 0;
- for (i = 0; i < length - 1; i++) {
- for (j = i + 1; j < length; j++) {
- if (array[i] < array[j]) {
- temp = array[i];
- array[i] = array[j];
- array[j] = temp;
- }
- }
- }
- //重新赋值给jobjectArray
- for (j = 0; j < length; j++) {
- jobject object = env->GetObjectArrayElement(integerArray, j);
- if( NULL != object){
- //通过jfieldID
- env->SetIntField(object, valueFieldID, array[j]);
- }
- }
- return integerArray;
- }
上面是重新赋值给integerArray,我们也可以重新创建新的jobjectArray。
在上面基础上修改,赋值那部分进行替换即可。
- //创建Integer的jobjectArray,并把array赋值给新的对象数组
- jobjectArray newIntegerArray = env->NewObjectArray(length, integerClass, NULL);
- jobject integerObject = NULL;
- for (j = 0; j < length; j++) {
- //创建jobject对象
- integerObject = env->AllocObject(integerClass);
- //给jobject赋值
- env->SetIntField(integerObject, valueFieldID, array[j]);
- //创建的jobject赋值到新的数组中
- env->SetObjectArrayElement(newIntegerArray, j, integerObject);
- }
- //释放局部引用
- env->DeleteLocalRef(integerObject);
参考文章
《》
《》
《》
© 版权声明