jni回调java类中函数_NDK开发:JNI回调函数的实现

#include

#include

#include

#define _JNI_VERSION JNI_VERSION_1_4

#define THREAD_NAME "lib_hello_jni"

JNIEnv *jni_get_env(const char *name);

/* * Pointer to the Java virtual machine * Note: It's okay to use a static variable for the VM pointer since there * can only be one instance of this shared library in a single VM */

static JavaVM *myVm;

static pthread_key_t jni_env_key;

static jobject callback_obj = NULL;

/* * This function is called when a thread attached to the Java VM is canceled or * exited */

static void jni_detach_thread(void *data) {

(*myVm)->DetachCurrentThread(myVm);

}

JNIEnv *jni_get_env(const char *name) {

JNIEnv *env;

env = pthread_getspecific(jni_env_key);

if (env == NULL) {

if ((*myVm)->GetEnv(myVm, (void **) &env, _JNI_VERSION) != JNI_OK) {

/* attach the thread to the Java VM */

JavaVMAttachArgs args;

jint result;

args.version = _JNI_VERSION;

args.name = name;

args.group = NULL;

if ((*myVm)->AttachCurrentThread(myVm, &env, &args) != JNI_OK)

return NULL;

/* Set the attached env to the thread-specific data area (TSD) */

if (pthread_setspecific(jni_env_key, env) != 0) {

(*myVm)->DetachCurrentThread(myVm);

return NULL;

}

}

}

return env;

}

/** * java文件在执行System.loadLibrary("hello-jni"); 的时候会调用此方法 */

jint JNI_OnLoad(JavaVM *vm, void *reserved) {

JNIEnv *env = NULL;

// Keep a reference on the Java VM.

myVm = vm;

if ((*vm)->GetEnv(vm, (void **) &env, _JNI_VERSION) != JNI_OK)

return -1;

/* Create a TSD area and setup a destroy callback when a thread that * previously set the jni_env_key is canceled or exited */

if (pthread_key_create(&jni_env_key, jni_detach_thread) != 0)

return -1;

return _JNI_VERSION;

}

void Java_com_example_hellojni_HelloJni_setValueSetCallback(JNIEnv *env, jobject thiz,jobject callback) {

if (callback_obj != NULL)

(*env)->DeleteGlobalRef(env, callback_obj);

//callback就是java层传进来的回调事件,在这里赋值给一个全局变量

callback_obj = callback ? (*env)->NewGlobalRef(env, callback) : NULL;

}

//内部回调处理函数

void jni_callback(jstring value) {

JNIEnv *env;

if (!(env = jni_get_env(THREAD_NAME)))

return;

if (callback_obj == NULL) {

return;

}

//GetObjectClass是通过传入jni中的一个java的引用来获取该引用的类型。

//FindClass是通过传java中完整的类名来查找java的class,

jclass cls = (*env)->GetObjectClass(env, callback_obj);

//根据class以及方法名、参数信息获取medthodId

//onValueSet就是方法名称,(Ljava/lang/String;)V中的Ljava/lang/String;代表该方法的参数类型,V代表Void,是方法返回类型

//如果一个方法名称为abc,有两个int参数,返回值为String则应该写作:(*env)->GetMethodID(env, cls, "abc", "(II)Ljava/lang/String")

jmethodID methodId = (*env)->GetMethodID(env, cls, "onValueSet", "(Ljava/lang/String;)V");

//根据methodId执行这个方法,最后的value是参数,注意这个value必须为jstring类型的,否则报错

(*env)->CallVoidMethod(env, callback_obj, methodId, value);

//清除cls引用

(*env)->DeleteLocalRef(env, cls);

}

void Java_com_example_hellojni_HelloJni_setValue(JNIEnv *env, jobject thiz, jstring value) {

// char *tmp = (*env)->GetStringUTFChars(env, value, NULL);

jni_callback(value);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值