使用jni直接訪問java物件中的欄位
阿新 • • 發佈:2019-02-17
Java類:UserInfo
public class UserInfo { static { System.loadLibrary("userinfo"); } // 從JNI中直接訪問欄位 public String mUserName; public int mUserAge; public long mMoney; public UserInfo() { } public int getUserAge() { return mUserAge; } public native void setUserName(String name); public native void setUserAge(int age); public native void setUserMoney(long money); }
其中三個設定方法,期望使用C實現,這裡涉及到JNI中的幾個函式:
1、FindClass:找到某個類,並返回jclass物件
2、GetObjectClass: 獲取到某個物件的型別,並返回jclass物件
3、GetFieldID:獲取到欄位的ID
4、SetIntField/SetLongField/SetObjectField:為欄位設值
基於上面的幾個方法,可以編寫程式碼如下:
編寫Android.mk後編譯,可以測試通過。/* * Class: com_iflytek_testjni_UserInfo * Method: setUserName * Signature: (Ljava/lang/String;)V */ JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserName(JNIEnv *env, jobject obj, jstring jstr) { jfieldID fid; jclass cls = (*env)->GetObjectClass(env, obj); fid = (*env)->GetFieldID(env, cls, "mUserName", "Ljava/lang/String;"); (*env)->SetObjectField(env, obj, fid, jstr); } /* * Class: com_iflytek_testjni_UserInfo * Method: setUserAge * Signature: (I)V */ JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserAge(JNIEnv *env, jobject obj, jint age) { jclass objClass = (*env)->FindClass(env, "com/iflytek/testjni/UserInfo"); jfieldID ageID = (*env)->GetFieldID(env, objClass, "mUserAge", "I"); (*env)->SetIntField(env, obj, ageID, (int)age); } /* * Class: com_iflytek_testjni_UserInfo * Method: setUserMoney * Signature: (J)V */ JNIEXPORT void JNICALL Java_com_iflytek_testjni_UserInfo_setUserMoney(JNIEnv *env, jobject obj, jlong money) { jclass objClass = (*env)->FindClass(env, "com/iflytek/testjni/UserInfo"); jfieldID id = (*env)->GetFieldID(env, objClass, "mMoney", "J"); (*env)->SetLongField(env, obj, id, (long)money); }
注意:由於方法簽名、欄位名稱都是寫死在C語言中的,因此程式碼不能混淆。