Jni 多執行緒程式設計,子執行緒回撥java方法
阿新 • • 發佈:2019-02-17
由於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();//執行緒結束釋放
}
}