您的位置:首页 > 编程语言 > Java开发

Jni 多线程编程,socket通讯数据主动回调java

2017-12-13 11:57 423 查看

由于c++层接收到服务端主动推送tcp数据,所以存在将c++层接收到的socket数据通过层层回调至java的需求。

以下为c++代码段:

1:在c++头文件中定义申明相应回调函数指针

typedef void (*SwitchStateChangeCallback)(char *pchar);//定义服务器主动回调函数
SwitchStateChangeCallback switchStateChangeCallback;//申明函数回调


2:jni中实现相应回调方法

void SwitchCallbackToJni(char *pchar) {
LOGD("callback jni:%s",pchar);
jclass jclassobj = threadEnv->GetObjectClass(gs_object);
jmethodID method = threadEnv->GetMethodID(jclassobj,"swithDataCallback","(ZLjava/lang/String;)V");
if(method == NULL)
{
LOGD("can't find Method swithDataCallback(boolean,String)");
}
threadEnv->CallVoidMethod(gs_object,method,TRUE,CharTojstring(threadEnv,pchar));
}


3:在jni调用函数时将相应回调函数设置至c++中

smartSwitch = new SmartHomeSwitch();
smartSwitch>setSwitchStateChangeCallback(SwitchCallbackToJni);


4:在c++代码适当位置回调预存的jni方法

switchStateChangeCallback(pCharResponse); //回调至jni层

注意问题

由于c++主动回调是无法携带相应的jni env 和 jobect 主要为了不耦合,不希望在c++类中引入到jni相关的头文件,所以只能回调相应数据到jni层,交由jni自由处理,所以需要预先保存好jniEnv 和 相应 的jclass,(如果存在多线程,并在子线程中调用回调,主线程的jni env将不可用(线程独立),此时需单独获取子线程中jni env指针,并在线程结束前释放)

int retGvm=env->GetJavaVM(&gs_jvm);//保存jvm
gs_object=env->NewGlobalRef(jObj);//保存obj


线程内获取与释放jni env指针

void ThreadChangeJniCallback(bool isRun){
if(isRun){
gs_jvm->AttachCurrentThread(&threadEnv, NULL);//线程开始获取
}else{
gs_jvm->DetachCurrentThread();//线程结束释放
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: