C++主線程調(diào)用Java方法
主要步驟
- 1、根據(jù)jobject獲取jclass(靜態(tài)方法就不用這一步了),如:
jclass clz = env->GetObjectClass(jobj);
- 2、獲取jmethodid,如:
jmethodid jmid =
env->GetMethodID(clz, "onError", "(ILjava/lang/String;)V")
- 3、調(diào)用方法,如:
jenv->CallVoidMethod(jobj, jmid, code, jmsg)
C++子線程調(diào)用Java方法
在子線程中調(diào)用java方法卻不能采用在主線程中調(diào)用的方式,因為調(diào)用java方法是要用JNIEnv去調(diào)用的,但是JNIEnv是線程相關(guān)的,子線程中不能直接使用創(chuàng)建線程的JNIEnv,所以需要JVM進(jìn)程相關(guān)的,可以通過JVM來獲取當(dāng)前線程的JNIEnv,然后就可以調(diào)用java方法了。
主要步驟
- 1、獲取JVM對象
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved);
- 2、通過JVM對象獲取JNIEnv
JNIEnv *env;
jvm->AttachCurrentThread(&env,0);//拿到env
/**
* Call Java Method
*/
jvm->DetachCurrentThread();
示例
JavaListener.h
class JavaListener {
public:
JavaVM *jvm;
jobject jobj;//類的對象
_JNIEnv *jenv;
jmethodID jmid;
public:
JavaListener(JavaVM *vm,_JNIEnv *env,jobject obj);
~JavaListener();
/**
* threadType:
* 1-主線程
* 0-子線程
*/
void onError(int threadType,int code, const char *msg);
};
JavaListener.cpp
/**
* 構(gòu)造方法,做初始化
*/
JavaListener::JavaListener(JavaVM *vm, _JNIEnv *env, jobject obj) {
jvm = vm;
jobj = obj;
jenv = env;
jclass clazz = env->GetObjectClass(jobj);
if (!clazz) {
return ;
}
jmid = env->GetMethodID(clazz,"onError","(ILjava/lang/String;)V");
}
void JavaListener::onError(int threadType, int code, const char *msg) {
if (threadType == 1){//
jstring jmsg = jenv->NewStringUTF(msg);
jenv->CallVoidMethod(jobj,jmid,code,jmsg);
jenv->DeleteLocalRef(jmsg);
} else {
JNIEnv *env;
jvm->AttachCurrentThread(&env,0);//拿到env
jstring jmsg = env->NewStringUTF(msg);
env->CallVoidMethod(jobj,jmid,code,jmsg);
env->DeleteLocalRef(jmsg);
jvm->DetachCurrentThread();
}
}