cocos2d-x 中多线程的cc++代码通过JNI调用java代码

cocos2d-x 中多线程的cc++代码通过JNI调用java代码,第1张

概述2014-01-02 15:49  1923人阅读 转载请注明原地址: http://blog.csdn.net/wu4long/article/details/17757433 这个文章为android multithread in c/c++ to call JNI 的第二篇。 第一篇地址为:http://blog.csdn.net/wu4long/article/details/177564 2014-01-02 15:49 1923人阅读 转载请注明原地址: http://blog.csdn.net/wu4long/article/details/17757433
这个文章为androID multithread in c/c++ to call JNI 的第二篇。
第一篇地址为:http://blog.csdn.net/wu4long/article/details/17756419
上文提到, androID的第三种方法,通过 ClassLoader object 来处理了。 Cache a reference to theClassLoaderobject somewhere handy,and issueloadClasscalls directly. This requires some effort.

哪怎样处理呢(This requires some effort) ?

下面我就以cocos2d-x的环境来具体描述吧。当然不是这个环境的也可以自己来稍微修改下。

此文方法是参照http://stackoverflow.com/questions/13263340/findclass-from-any-thread-in-androID-jni

FindClass from any thread in Android JNI 不过此文章不是针对cocos2d-x来写的。有些地方给出的代码不严谨。


///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();

@H_404_305@ 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)

{

m_psJavaVM= javaVM;

initClassLoaderForMultiThread();

然后修改 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代码所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1067965.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存