1. 程式人生 > >Android JNI中Java與C++物件如何建立一一對應的關係

Android JNI中Java與C++物件如何建立一一對應的關係

Android JNI中Java與C++物件如何建立一一對應的關係

環境

系統:Mac OSX
IDE:android studio 3.0

1.JAVA物件持有C++物件的指標

  • 在java類中建立long型別的變數如(long mNativeStudent ),用於儲存c++物件的指標,java程式碼如下;
public class Student {

   private long mNativeStudent = -1; // 用於存放 c++ 物件的指標
   private final String TAG = "Student";
   public
Student(){ mNativeStudent = CreateStudent(); } public void setName(String name){ SetName(name); } public String getName(){ return GetName(); } public void setGrade(int grade){ SetGrade(grade); } public int getGrade(){ return GetGrade(); } public
String print(){ return Print(); } public static String printClassName(){ return PrintClassName(); } @Override protected void finalize() throws Throwable { DestoryStudent(mNativeStudent); super.finalize(); } private native long CreateStudent(); private
native void DestoryStudent(long nativeStuent); private native void SetName(String name); private native String GetName(); private native void SetGrade(int grade); private native int GetGrade(); private native String Print(); private static native String PrintClassName(); }
  • 在建立C++物件(如NativeStudent)的本地方法中,將C++物件的指標存入java變數中(mNativeStudent)
jlong CreateStudent(JNIEnv *env, jobject obj){
    NativeStudent *student = new(std::nothrow) NativeStudent();
    if(student){
        return (jlong)student;
    }else{
        LOGE("new NativeStudent object error.");
    }
}
  • 如果要取得C++物件,則通過mNativeStudent的獲取C++物件的指標
NativeStudent * GetNativeStudentFromObj(JNIEnv *env, jobject obj){
    jclass objClazz = (jclass)env->GetObjectClass(obj);//obj為對應的Java物件
    if (objClazz == NULL){
        LOGE("env->GetObjectClass return null.");
        return nullptr;
    }
    jfieldID fid = env->GetFieldID(objClazz, "mNativeStudent", "J");
    if(fid == NULL){
        LOGE("env->GetFieldID error.");
        return nullptr;
    }
    jlong p = (jlong)env->GetLongField(obj, fid);
    return (NativeStudent *)p;
}

2.C++物件持有JAVA物件的引用

  • 在C++類中建立一個long型別的變數(如long mJavaObj),用於儲存JAVA物件的引用
  • 在建立C++物件時,儲存JAVA物件的引用
jlong CreateStudent(JNIEnv *env, jobject obj){
    NativeStudent *student = new(std::nothrow) NativeStudent();
    jobject gThiz = (jobject)env->NewGlobalRef(obj);//thizJAVA物件
    student->mJavaObj = (jint)gThiz; //c++物件儲存java引用
    if(student){
        return (jlong)student;
    }else{
        LOGE("new NativeStudent object error.");
    }
}
  • 注意在銷燬c++物件是要呼叫DeleteGlobalRef方法銷燬全域性引用
void DestoryStudent(JNIEnv *env, jobject obj, jlong nativeStudent){
    NativeStudent *student = (NativeStudent*)nativeStudent;
    env->DeleteGlobalRef((jobject)student->mJavaObj); //銷燬建立的引用
    IL_SAFE_DELETE(student);
}

demo地址