java传递对象给C++的处理过程

来源:互联网 发布:mac u盘4g以上文件 编辑:程序博客网 时间:2024/04/28 22:35

目前工作从事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++利用这些数据信息做一些逻辑处理。
  }

 

原创粉丝点击