В JNI я вызываю настраиваемый объект массива. Я получил его тип из foo.getclass (). GetName () и использовал его для получения GetFieldID. Тип выглядит так: [L полностью определенное-имя-класса.
В SDK 25 я могу получить GetObjectField без каких-либо ошибок.
В SDK 26 я получаю следующую ошибку:
A/zygote64: java_vm_ext.cc:534] JNI DETECTED ERROR IN APPLICATION: JNI GetObjectField called with pending exception java.lang.NoSuchFieldError: no type "[Lcom..customClassName;" found and so no field "fieldname" could be found in class "Lcom..parentClass;" or its superclasses
Мне известно, что есть некоторые изменения в новом SDK. Но я не уверен, как это изменить, чтобы не было ошибки. Спасибо.
Не уверен в комментарии @ Alex, так как я не смог его попробовать.
Я нашел этот обходной путь,
Сторона Java:
Класс настраиваемого объекта, ClassA, имеет объект массива этого класса КлассB, как показано ниже.
public ClassB objb[] = new ClassB[size];
Теперь вместо того, чтобы отправлять в JNI только объект ClassA, я отправил отдельно объект ClassA и КлассB. Начиная с JNI, он не принимает пользовательский тип объекта из SDK 26.
sendA(obja);
sendB(obja.objb[0]);
Сторона JNI:
ClassA a;
//sendA function for classA similiar as below.
extern "C"
JNIEXPORT jint JNICALL
Java_<PATH_TO_FUNCTION>_sendB(JNIEnv *env,jobject instance,jobject BObj) {
LOGD(TAG,"sendB: START");
jclass jBClass=env->FindClass("com/< path to class separated by '/' >");
// int Field jbid
jfieldID jbid = env->GetFieldID(jBClass, "bId", "I");
jint bId = env->GetIntField(BObj, jbid);
obja.objb[0].bId = (int) bId;
LOGI(TAG, "\t bId[%d]: %d ", 0, obja.objb[0].bId);
return 0;
}
Для итерации вы можете использовать для цикла на стороне Java и отправить итератор в качестве параметра sendA () и sendB () в JNI.
Кроме того, существует способ преобразования объекта сериализация в строку и десериализация его обратно в объект со стороны JNI. Но, будучи новичком в JNI, я не был достаточно уверен, чтобы десериализовать объект настраиваемого массива на стороне JNI.
Попробуйте использовать GetObjectArrayElement () для первого элемента массива и получить его класс с помощью GetObjectClass (). Имена классов могут быть менее надежными.