Android JNI Development Series (X) JNI Accessing Java Instance Variables and Static Variables

Keywords: Mobile Java Attribute jvm

JNI accesses Java instance variables and static variables

Instance variables and static variables in Java, how to access and modify them in local code. Static variables, also known as class variables (attributes), share the same data in all instance objects and can be accessed directly by class name and variable name. Instance variables are also called member variables (attributes). Each instance has a copy of instance variable data, and the modified data does not affect each other.

Code directly:

JAVA

public class Person {

    //Member variables 
    private String hobby;

    //Static variables
    private static int happiness;

    public String getHobby() {
        return hobby;
    }

    public static int getHappiness() {
        return happiness;
    }

    //Setting the value of the member variable in the Native method
    public native boolean setHobby();
    
    //Setting the value of the static variable in the Native method
    public native boolean setHappiness();
}

Native

JNIEXPORT jboolean JNICALL
Java_org_professor_jni_bean_Person_setHobby(JNIEnv *env, jobject instance) {

//1. Getting Class Objects of Class Types
jclass personClass = (*env)->FindClass(env, "org/professor/jni/Person");
if (NULL == personClass) {
    __android_log_print(ANDROID_LOG_ERROR, "PERSON", "NOT FIND CLASS");
    return JNI_FALSE;
}
//2. Get attribute ID
jfieldID hobbyFiledID = (*env)->GetFieldID(env, personClass, "hobby", "Ljava/long/String");

if (NULL == hobbyFiledID) {
    __android_log_print(ANDROID_LOG_ERROR, "PERSON", "NOT FIND Hobby FiledID");
    return JNI_FALSE;
}

//3. Instance attributes, get attribute values through objects
jstring hobbyFiledStr = (*env)->GetObjectField(env, instance, hobbyFiledID);
if (NULL != hobbyFiledStr) {
    const char *hobby = (*env)->GetStringUTFChars(env, hobbyFiledStr, NULL);
    if (NULL != hobby) {
        __android_log_print(ANDROID_LOG_ERROR, "PERSON Hobby", hobby);
        (*env)->ReleaseStringChars(env, hobbyFiledStr, hobby);
    }
}
//4. Setting property values
jstring jHobby = (*env)->NewStringUTF(env, "BASKETBALL,RUN");
(*env)->SetObjectField(env, instance, hobbyFiledID, jHobby);
//5. Delete local reference variables
(*env)->DeleteLocalRef(env, personClass);
(*env)->DeleteLocalRef(env, hobbyFiledStr);
(*env)->DeleteLocalRef(env, jHobby);
return JNI_TRUE;
}


JNIEXPORT jboolean JNICALL
Java_org_professor_jni_bean_Person_setHappiness(JNIEnv *env, jobject instance) {

//1. Getting Class Objects of Class Types
jclass personClass = (*env)->FindClass(env, "org/professor/jni/Person");
if (NULL == personClass) {
    __android_log_print(ANDROID_LOG_ERROR, "PERSON", "NOT FIND CLASS");
    return JNI_FALSE;
}
//2. Get attribute ID

jfieldID happinessFiledID = (*env)->GetStaticFieldID(env, personClass, "happiness", "I");

if (NULL == happinessFiledID) {
    __android_log_print(ANDROID_LOG_ERROR, "PERSON", "NOT FIND Happiness FiledID");
    return JNI_FALSE;
}

//3. Getting static attribute values
jint happinessValue = (*env)->GetStaticIntField(env, personClass, happinessFiledID);
if (NULL != happinessValue) {
    __android_log_print(ANDROID_LOG_ERROR, "PERSON happinessValue = %d",
                        (const char *) happinessValue);
}

//4. Setting static property values
(*env)->SetStaticIntField(env, personClass, happinessFiledID, 80);

//5. Delete local reference tables without requiring basic data types
(*env)->DeleteLocalRef(env, personClass);
return JNI_TRUE;
}

Summary

  • Because JNI functions operate directly on data structures in JVM, they are not restricted by Java access modifiers. That is, calling JNI functions in Native code can access non-public attributes and methods in Java objects.
  • Accessing and modifying instance variables operation steps:
    • Call the GetObjectClass function to get the Class reference of the instance object
    • Call the GetField ID function to get the ID of an instance variable in the Class reference
    • Calling the GetXXXField function to get the value of the variable requires passing in the object to which the instance variable belongs and the variable ID.
    • Calling the SetXXXField function to modify the value of a variable requires passing in the object to which the instance variable belongs, the variable ID, and the value of the variable.
  • Access and Modify Static Variable Operations Step:
    • Call the FindClass function to get the Class reference of the class
    • Call the GetStaticField ID function to get the ID of a static variable in the Class reference
    • Calling the GetStaticXXXField function to get the value of a static variable requires passing in a reference to the Class to which the variable belongs and a variable ID
    • Calling the SetStaticXXXField function to set the value of a static variable requires passing in the reference of the Class to which the variable belongs, the variable ID, and the value of the variable.

Posted by adrafa on Sat, 02 Feb 2019 01:18:15 -0800