Search code examples
androidjava-native-interfaceandroid-10.0

How to set IntField from native jni to Java Android 10


After update my project to support Android 10, a crash produced in the JNI level related to non-SDK interface restrictions in Android 10 :

 JNI DETECTED ERROR IN APPLICATION: JNI SetIntField called with pending exception java.lang.NoSuchFieldError: no "I" field "value" in class "Ljava/lang/Integer;" or its superclasses

which come from this part of code :

jclass clazz = (*env)->GetObjectClass(env, outputObj);
jfieldID mi = (*env)->GetFieldID(env, clazz, "value", "I");
(*env)->SetIntField(env, outputObj, mi, pListLen);

To fix that i replace it by :

jclass clazz = (*env)->GetObjectClass(env, outputObj);
jmethodID intValueMethod = (*env)->GetMethodID(env, clazz, "intValue", "()I");
jint result = (*env)->CallIntMethod(env, outputObj,intValueMethod,pListLen);

After that my application doesn't crash and find the integer value correctly, but i want to set the result integer on Java code using the same method SetIntField.

Could you please give me a way or method to set the result on the Java part.


Solution

  • As changing the intger field is not a good practice on JNI part, so i changed the way instead changing it by reflection method

        jclass clazz = (*env)->GetObjectClass(env, outputBufLen);
        jmethodID value_of = (*env)->GetStaticMethodID(env,clazz, "valueOf", "(I)Ljava/lang/Integer;");
        jobject result = (*env)->CallStaticObjectMethod(env,clazz, value_of, pOutBufLen);
    

    I set the result under an int Array and i return it :

    int result = (*env)->CallStaticObjectMethod(env,clazz, value_of, pOutBufLen);
    
    jintArray resultArray = (*env)->NewIntArray(env, 2);
    jint fill[2];
    fill[0] = result;
    fill[1] = (jint) pOutBufLen;
    (*env)->SetIntArrayRegion(env, result, 0, 2, fill);
    
    return (resultArray);