大佬教程收集整理的这篇文章主要介绍了cocos2d-x 中多线程的c/c++代码通过JNI调用java代码,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
ClassLoader
object
来处理了。
ClassLoader
object somewhere hAndy,and issueloadClass
calls directly. This requires some effort.哪怎样处理呢(This requires some effort) ?
下面我就以cocos2d-x的环境来具体描述吧。当然不是这个环境的也可以自己来稍微修改下。
此文方法是参照http://stackoverflow.com/questions/13263340/findclass-from-any-thread-in-android-jni
///return true if success. else return false.
boolyour_thread_start_javaVMAttachCurrentThread()
JNIEnv* env = NULL;
if( JniHelper::getJavaVM()->AttachCurrentThread(&env,NULL) < 0) return false;
return true;
}
void your_thread_stop_javaVMDetachCurrentThread()
JniHelper::getJavaVM()->DetachCurrentThread();
}
在线程函数中开始调用 your_thread_start_javaVMAttachCurrentThread(),线程结束的地方调用your_thread_stop_javaVMDetachCurrentThread()。 错误处理自己去处理吧。上面的两个函数你可以放置在你的认为合适的地方。当然也可以直接放置在JniHelper的类中。自行处理吧。
为了可以继续使用JniHelper的方法,透明的规避多线程的问题。我们就直接修改JniHelper.cpp文件。
staticjobject gClassLoader;
jmethodIDgFindClassMethod;
增加一个新的函数:
static void initClassLoaderForMultiThread()
JNIEnv*env = 0;
do
if(! getEnv(&env))
break;
}
jclasscocos2dClass = env->FindClass("org/cocos2dx/lib/Cocos2dxRenderer");
if(env->Exceptioncheck())
env->ExceptionDescribe();
env->ExceptionClear();
LOGD("ExceptioninitClassLoaderForMultiThreadcocos2dClass is exception");
break;
}
///env->FindClass("java/lang/Class");
jclassclassClass = env->GetObjectClass(cocos2dClass);
if(env->Exceptioncheck())
env->ExceptionDescribe();
env->ExceptionClear();
LOGD("ExceptioninitClassLoaderForMultiThreadclassClass is exception");
break;
}
jclassclassLoaderClass = env->FindClass("java/lang/ClassLoader");
initClassLoaderForMultiThreadclassLoaderClass"break;
}
jmethodIDgetClassLoaderMethod = env->GetMethodID(classClass,"getClassLoader",
"()Ljava//ClassLoader;");
jobjectclassLoader = env->CallObjectMethod(cocos2dClass,getClassLoaderMethod);
initClassLoaderForMultiThreadclassLoader"break;
}
gClassLoader = env->NewGlobalRef(classLoader);
jmethodIDfindClassMethod = env->GetMethodID(classLoaderClass,255)">"findClass", "(/String;)/Class;");
gFindClassMethod = findClassMethod;
if(env->Exceptioncheck())
env->ExceptionDescribe();
env->ExceptionClear();
gFindClassMethod = NULL;
gClassLoader = NULL;
initClassLoaderForMultiThreadfindClassMethod"break;
}
}while(0);
}
然后在JniHelper::setJavaVM 函数中调用上面的函数。如下所示:
voidJniHelper::setJavaVM(JavaVM*javaVM)
@H_529_528@m_psJavaVM= javaVM;
然后修改 getClassID_ 函数. 添加下面灰色阴影的部分。即在原有的FindClass失败的时候,
用我们新的ClassLoader的方法来查找类。
ret =static_cast<jclass>(pEnv->CallObjectMethod(gClassLoader,gFindClassMethod,jstrName));
jclassgetClassID_(constchar*className,65)">JNIEnv*env)
JNIEnv*pEnv = env;
jclassret = 0;
do
if(! pEnv)
if(! getEnv(&pEnv))
break;
}
}
ret = pEnv->FindClass(className);
if(! ret)
if(gClassLoader)
if(pEnv->Exceptioncheck())
pEnv->ExceptionDescribe();
pEnv->ExceptionClear();
}
jString jstrName = (pEnv)->NewStringUTF(className);
ret = static_cast<jclass>(pEnv->CallObjectMethod(gClassLoader,jstrName));
if(ret) break;
}
LOGD("Failed to find class of %s",className);
}while(0);
returnret;
}
然后在你的线程代码中,可以使用JniHelper来调用相应的方法了。
JniHelper::getStaticMethodInfo 等方法和本来单线程的就一样了。
大功告成了。已经可以透明处理多线程了。
如果你的环境不是cocos2dx,只需要修改将上面添加的部分移到你的环境中就可以了。
唯一的区别,就是将这句
jclasscocos2dClass = env->FindClass("org/cocos2dx/lib/Cocos2dxRenderer");
中的字符串org/cocos2dx/lib/Cocos2dxRenderer 换成你的环境中肯定存在的java类就可以了。
补充线程的资源同步:
如果线程间需要用到java端的资源同步。可以使用jint MonitorEnter(jobject obj); 和 jint MonitorExit(jobject obj);
类似一个简单的同步锁,在Java中我们这样写
synchronized (obj) {
//dosomething
}
在JNI中,我们使用这组函数这样写。 当然首先通过Jni的方法来获取这个对象。
jobject obj = ….;
env->MonitorEnter(obj);
//dosomething env->MonitorExit(obj);
以上是大佬教程为你收集整理的cocos2d-x 中多线程的c/c++代码通过JNI调用java代码全部内容,希望文章能够帮你解决cocos2d-x 中多线程的c/c++代码通过JNI调用java代码所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。