java傳遞對象給C++的處理過程

目前工作從事android平臺下NDK編程,所以不得不學習jni機制,這幾天對Java層傳遞對象給C++層(jni層)的處理過程做出了分析,並得出以下總結:

在這裏我們假設java層一個本地方法:public static native void native_setfolers_list(ArrayList<AppInfo> childArr);

C++層(jni層)對這個本地方法進行具體實現,如下:

/*在進行以下工作時,我們知道java層的childArr對象中有兩個方法get(int i)和size()*/

/*如果直接在java層使用這兩個方法,直接調用即可,但是在childArr傳遞到了C++層就不能按照java層的方式來調用這兩個方法了*/

//java層的對象類型ArrayList<AppInfo>傳遞到C++層,需要用jobject類型來接收

void native_setfolders_list(JNIEnv *env,jclass clazz,jobject arr)
{

 jclass cls_arraylist = env->GetObjectClass(arr); //在C++層如果想調用get和size兩個方法,就必須把對象jobject類型轉化爲jclass類型
 jmethodID arraylist_get = env->GetMethodID(cls_arraylist,"get","(I)Ljava/lang/Object;");//GetMethodID方法參數依次意思:接收java層的對象的jclass類型;接收java層對象中get方法名稱;get方法的參數類型以及返回類型。
 jmethodID arraylist_size = env->GetMethodID(cls_arraylist,"size","()I"); //同理  
 jint len = env->CallIntMethod(arr,arraylist_size);  //CallIntMethod方法參數依次意思:接收java層的對象的jobject類型;接收java層對象中方法size的ID。len是size方法的返回值,即java層傳遞過來的對象childArr的大小(也就是數組鏈表裝載的AppInfo對象的個數).

/*以下就是利用java層傳遞過來的對象childArr中的get方法依次遍歷得到所有的AppInfo對象,並得到AppInfo對象裏的所有數據成員*/

 for(int i=0;i<len;i++)
 {
  jobject obj_appinfo = env->CallObjectMethod(arr,arraylist_get,i);     //CallObjectMethod方法參數依次意思:接收java層的對象的jobject類型;接收java層對象中方法get的ID;接收java層對象中方法get中的實參。返回值obj_appinfo是接收java層的對象childArr中的裝載對象AppInfo的jobject類型。
  jclass cls_appinfo = env->GetObjectClass(obj_appinfo);  //把接收java層的對象childArr中的裝載對象AppInfo的jobject類型jclass類型化

  
 jfieldID jfid0 = env->GetFieldID( cls_appinfo, "appID", "I" );     //GetFieldID方法參數依次意思:接收java層的對象childArr中的裝載對象AppInfo的jclass類型;接收java層的對象childArr中的裝載對象AppInfo中的數據成員名稱;接收java層的對象childArr中的裝載對象AppInfo中的數據成員類型。返回值jfid0 是接收java層的對象childArr中的裝載對象AppInfo中的數據成員相應的數據ID。
 jint appID = env->GetIntField( obj_appinfo, jfid0 );  //GetIntField方法參數依次意思:接收java層的對象childArr中的裝載對象AppInfo的jobject類型;接收java層的對象childArr中的裝載對象AppInfo中的數據成員的數據ID。返回值appID是接收java層的對象childArr中的裝載對象AppInfo中的數據成員的值。

 jfieldID jfid1 = env->GetFieldID( cls_appinfo, "iconPosition", "I" ); //得到數據成員iconPosition的數據ID
 jint iconPosiotion = env->GetIntField( obj_appinfo, jfid1 ); //根據數據ID得到數據成員iconPosition的值

/*同理以下得到接收java層的對象childArr中的裝載對象AppInfo中的其他數據成員的值*/
 jfieldID jfid2 = env->GetFieldID( cls_appinfo, "parentFolderID", "I" );
 jint parentFolderID = env->GetIntField( obj_appinfo, jfid2 );
 jfieldID jfid3 = env->GetFieldID( cls_appinfo, "iconTextureID", "I" );
 jint iconTextureID = env->GetIntField( obj_appinfo, jfid3 );
 jfieldID jfid4 = env->GetFieldID( cls_appinfo, "appNameTextureID", "I" );
 jint appNameTextureID = env->GetIntField( obj_appinfo, jfid4 );
 jfieldID jfid5 = env->GetFieldID( cls_appinfo, "appOrFolder", "Z" );
 jboolean appOrFolder = env->GetBooleanField( obj_appinfo, jfid5 );
 jfieldID jfid6 = env->GetFieldID( cls_appinfo, "preInstallApp", "Z" );
 jboolean preInstallApp = env->GetBooleanField( obj_appinfo, jfid6 );
 jfieldID jfid7 = env->GetFieldID( cls_appinfo, "folderEmpty", "Z" );
 jboolean folderEmpty = env->GetBooleanField( obj_appinfo, jfid7 );
 jfieldID jfid8 = env->GetFieldID(cls_appinfo, "lengthRatio", "F");
 jfloat lengthRatio = env->GetFloatField(obj_appinfo,jfid8);

這裏我們最終把java層的對象ArrayList<AppInfo> childArr傳遞到C++層並利用childArr本身的get和size方法遍歷得到chidArr裝載所有的AppInfo對象,並得到每個AppInfo對象中的數據成員信息。

所以這裏根本就是在傳遞這些數據成員的信息,這裏可以定義一個結構體(這個結構體中有這些數據成員類型的變量),把這些數據成員信息賦給這個結構體對應的數據成員變量。每個結構體就代表着childArr對象中的每個AppInfo對象,儲存着許多數據信息。並在C++利用這些數據信息做一些邏輯處理。
  }

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章