C++主线程调用Java方法
主要步骤
- 1、根据jobject获取jclass(静态方法就不用这一步了),如:
jclass clz = env->GetObjectClass(jobj);
- 2、获取jmethodid,如:
jmethodid jmid =
env->GetMethodID(clz, "onError", "(ILjava/lang/String;)V")
- 3、调用方法,如:
jenv->CallVoidMethod(jobj, jmid, code, jmsg)
C++子线程调用Java方法
在子线程中调用java方法却不能采用在主线程中调用的方式,因为调用java方法是要用JNIEnv去调用的,但是JNIEnv是线程相关的,子线程中不能直接使用创建线程的JNIEnv,所以需要JVM进程相关的,可以通过JVM来获取当前线程的JNIEnv,然后就可以调用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
/**
* 构造方法,做初始化
*/
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();
}
}
网友评论