Android jni c/c++传递实体类到java

来源:互联网 发布:绝地求生优化 编辑:程序博客网 时间:2024/06/08 07:05

上一篇文章讲了c/c++与java之间如何传递参数,但是有些时候c层会传递过来一个实体类,最开始,我是把实体类里面的参数都拆出来,一个一个传递到java层去,这样实现上没任何问题,但是太过繁琐。就去找了直接传递实体类的方法。
传递基础类型的方法,这里就不再赘述,有需要的可以看我上一篇博客。这里就在它的基础上进行讲解。

1.GetMethodID

jniobj->JNI_recLeft = env->GetMethodID(jniobj->g_class, "recLeft",         "(ILcom/arcvideo/rtcmessage/model/RtcClientModel;)V");

在这里调用了java里面一个recLeft方法,然后recLeft方法传递了一个RtcClientModel的实体类,这里就需要把它的类型名称写完整,从包名com开始,最前面要加上“L”跟“Ljava/langString”比较类似。

2.生成jobject

static jobject getRtcClientModel(RTCCLIENTMODEL* client){    MVLOG("RtcMessageJNI getRtcClientModel is start");    jclass jcInfo = jniobj->g_class_rtc_client_model;    jfieldID jfcid = jniobj->g_ThreadEnv->GetFieldID(jcInfo, "cid", "Ljava/lang/String;");//这里通过GetFieldID获取到实体类中的成员变量    jfieldID jfextInfo = jniobj->g_ThreadEnv->GetFieldID(jcInfo, "extInfo", "Ljava/lang/String;");    jobject joInfo = jniobj->g_ThreadEnv->AllocObject(jcInfo);//这里生成一个jobject对象    if(client == MNull){        MVLOG("RtcMessageJNI getRtcClientModel client is null");        return joInfo;    }    jstring jscid = jniobj->g_ThreadEnv->NewStringUTF(client->cid);//这里获取到jstring类型的参数值    jstring jsextInfo = jniobj->g_ThreadEnv->NewStringUTF(client->extInfo);    jniobj->g_ThreadEnv->SetObjectField(joInfo, jfcid, jscid);//这里把参数值设置到对应jobject的对应成员变量中去    jniobj->g_ThreadEnv->SetObjectField(joInfo, jfextInfo, jsextInfo);    MVLOG("RtcMessageJNI getRtcClientModel is success");    return joInfo;}

这里首先要获取到jclass对象

jclass jsRtcClientModel = env->FindClass(DL_CLASS_NAME_RTC_CLIENT_MODEL);        jniobj->g_class_rtc_client_model = (jclass)env->NewGlobalRef(jsRtcClientModel);//这里把它设置为全局变量

其他的在代码注释中有讲到,这样就获取到了jobject。最后把获取到的jobject对象传递到CallVoidMethod()方法中去,这样就传递到了java层去了。

3.java层

package com.arcvideo.rtcmessage.model;import java.io.Serializable;public class RtcClientModel implements Serializable {    public String cid;    public String extInfo;    public ConnectInfo connectInfo;    public String getCid() {        return cid;    }    public void setCid(String cid) {        this.cid = cid;    }    public String getExtInfo() {        return extInfo;    }    public void setExtInfo(String extInfo) {        this.extInfo = extInfo;    }    public ConnectInfo getConnectInfo() {        return connectInfo;    }    public void setConnectInfo(ConnectInfo connectInfo) {        this.connectInfo = connectInfo;    }}

首先定义好,需要调用的实体类。

public void recLeft(int sessionId, RtcClientModel client) {}

定义好要被c层调用的java方法,里面写好,刚才定义的java实体类。这样就大功告成了。

这里有个注意点,就是,获取jclass最好是在主线程中获取到,然后通过设置为全局变量,再来使用,否则有可能发生class not find的异常。因为两个线程里面,所用到的classloader可能不是同一个(加载基础类型是不会有问题的)。

原创粉丝点击