Android sdk 26 и далее - jni getobjectfield вызывается с ожидающим исключением java.lang.nosuchfielderror для настраиваемого объекта массива

В 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. Но я не уверен, как это изменить, чтобы не было ошибки. Спасибо.

Попробуйте использовать GetObjectArrayElement () для первого элемента массива и получить его класс с помощью GetObjectClass (). Имена классов могут быть менее надежными.

Alex Cohn 31.10.2018 17:03
1
1
369
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не уверен в комментарии @ 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.

Другие вопросы по теме