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

由于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();//线程结束释放
    }
}

猜你喜欢

转载自blog.csdn.net/qq_27688259/article/details/78790393