背景
最近有项目需求,需要在jni中创建多个子线程,并在子线程中,回调java将byte[]数据上报给java处理
demo实例
关键代码
static jmethodID method_callback;
jclass global_class = NULL;
jclass myClass = NULL;
JavaVM* gJavaVM = NULL;jint JNI_OnLoad(JavaVM *jvm, void* reserved) {JNIEnv *env;int status;jclass clazz;//全局变量报错jvmgJavaVM = jvm;if (jvm->GetEnv((void **) &env, JNI_VERSION_1_4)) {//ALOGE("JNI version mismatch error");return JNI_ERR;}clazz = env->FindClass(kClassPathName);//全局变量,保存class类global_class = (jclass)env->NewGlobalRef(clazz);//获取class类callback方法method_callback = (env)->GetStaticMethodID(clazz,"onFrameUpdate","([BI)V");if (NULL == clazz) {_err("Unable to find class com.autochips.avm.AVMCam");return -1;}env->NewGlobalRef(clazz);status = (env)->RegisterNatives(clazz, sMethods, sizeof(sMethods) / sizeof(sMethods[0]));if (status < 0) {return JNI_ERR;}return JNI_VERSION_1_4;
}// 子线程调用javaJNIEnv *env = NULL;int status;bool isAttached = false;status = gJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4);if (status < 0) {if (gJavaVM->AttachCurrentThread(&env, NULL))将当前线程注册到虚拟机中{return;}isAttached = true;}//实例化该类jobject jobject = env->AllocObject(global_class);//分配新 Java 对象而不调用该对象的任何构造函数。返回该对象的引用。jclass clazz = env->GetObjectClass(jobject);//调用Java方法avm_cam->get_buf(ch, &buf);jbyte* buffer = new jbyte[buf.width * buf.height * 3 /2];memcpy(buffer,buf.ptr,buf.width * buf.height * 3 /2);jbyteArray bytes = env->NewByteArray(buf.width * buf.height * 3 /2);env->SetByteArrayRegion(bytes,0,buf.width * buf.height * 3 /2,buffer);env->CallStaticVoidMethod(clazz, method_callback,bytes,buf.width * buf.height * 3 /2);env->DeleteLocalRef(bytes);if (isAttached) {gJavaVM->DetachCurrentThread();}
总结
网上查找了很多有关的文章,测试后都无法实现。最后通过下面关键代码实现。
jobject jobject = env->AllocObject(global_class);//分配新 Java 对象而不调用该对象的任何构造函数。返回该对象的引用。jclass clazz = env->GetObjectClass(jobject);这两句是比较关键