cocos2d-x 中多线程的c/c++代码通过JNI调用java代码(2)
jobject classLoader = env->CallObjectMethod(cocos2dClass, getClassLoaderMethod);
if(env->ExceptionCheck())
{
env->ExceptionDescribe();
env->ExceptionClear();
LOGD(Exception initClassLoaderForMultiThread classLoader);
break;
}
gClassLoader = env->NewGlobalRef(classLoader);
jmethodID findClassMethod = env->GetMethodID(classLoaderClass,findClass, (Ljava/lang/String;)Ljava/lang/Class;);
gFindClassMethod = findClassMethod;
if(env->ExceptionCheck())
{
env->ExceptionDescribe();
env->ExceptionClear();
gFindClassMethod = NULL;
gClassLoader = NULL;
LOGD(Exception initClassLoaderForMultiThread findClassMethod);
break;
}
}while(0);
}
然后在 JniHelper::setJavaVM 函数中调用上面的函数。如下所示:
void JniHelper::setJavaVM(JavaVM *javaVM)
{
m_psJavaVM = javaVM;
initClassLoaderForMultiThread(); }
然后修改 getClassID_ 函数. 添加下面灰色阴影的部分。即在原有的FindClass失败的时候,
用我们新的ClassLoader的方法来查找类。
ret = static_cast
static jclass getClassID_(constchar *className,JNIEnv *env)
{
JNIEnv *pEnv = env;
jclass ret = 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
if(ret) break;
}
LOGD(Failed to find class of %s, className);
break;
}
} while (0);
return ret;
}
然后在你的线程代码中,可以使用JniHelper来调用相应的方法了。
JniHelper::getStaticMethodInfo 等方法和本来单线程的就一样了。
大功告成了。已经可以透明处理多线程了。
如果你的环境不是cocos2dx,只需要修改将上面添加的部分移到你的环境中就可以了。
唯一的区别,就是将这句
jclass cocos2dClass = env->FindClass(org/cocos2dx/lib/Cocos2dxRenderer);
中的字符串org/cocos2dx/lib/Cocos2dxRenderer 换成你的环境中肯定存在的java类就可以了。
补充线程的资源同步:
如果线程间需要用到java端的资源同步。可以使用 jint MonitorEnter(jobject obj); 和 jint MonitorExit(jobject obj);
类似一个简单的同步锁,在Java中我们这样写
synchronized (obj) {
//dosomething
相关新闻>>
- 发表评论
-
- 最新评论 更多>>