java和c++通信比较麻烦,想实现一套通用的机制,android 发送一个通知到cocos2dx,
android 定义方法
public static native void postNotification(String notificaitonName,Map<String, String> map);
public static void sendNotificaiton(final String notificaitonName,final Map<String, String> map)
{
Cocos2dxGLSurfaceView.getInstance().queueEvent(new Runnable() {
@Override
public void run() {
postNotification(notificaitonName,map);
}
});
}
cocos2dx 实现
extern “C”
{
JNIEXPORT void JNICALL Java_tools_GameTools_postNotification(JNIEnv* env, jobject thiz,jstring notificaitonName,jobject hashMap)
{
//得到jni hashmap类
CCDictionary *dataDic=NULL;
if(hashMap)
{
jclass jclass_of_hashmap = (env)->GetObjectClass(hashMap);
//得到jni entryset方法
jmethodID entrySetMethod = (env)->GetMethodID(jclass_of_hashmap, “entrySet”, “()Ljava/util/Set;”);
//交用hashMap对象的entrySet方法,返回jni set对象
jobject jobject_of_entryset = env->CallObjectMethod(hashMap, entrySetMethod);
//得到jni Set类型
jclass jclass_of_set = (env)->FindClass("java/util/Set");
if (jclass_of_set == 0) {
//得到set类型失败
printf("java/util/Set lookup failed\n");
return;
}
//得到对象jclass_of_set 的 iterator方法
jmethodID iteratorMethod = env->GetMethodID(jclass_of_set, "iterator", "()Ljava/util/Iterator;");
//通过对象jobject_of_entryset 对象调用iterator 方法,得到jni itreator对象
jobject jobject_of_iterator = env->CallObjectMethod(jobject_of_entryset, iteratorMethod);
//得到Iterator类
jclass jclass_of_iterator = (env)->FindClass("java/util/Iterator");
//得到iterator hasNext方法
jmethodID hasNextMethod = env->GetMethodID(jclass_of_iterator, "hasNext", "()Z");
//调用hasNext方法
jboolean bHasNext = env->CallBooleanMethod(jobject_of_iterator, hasNextMethod);
jmethodID nextMethod = env->GetMethodID(jclass_of_iterator, "next", "()Ljava/lang/Object;");
dataDic=CCDictionary::create();
while (bHasNext) {
//得到实例类型
jclass jclass_of_mapentry = (env)->FindClass("java/util/Map$Entry");
jobject jobject_of_Entry=env->CallObjectMethod(jobject_of_iterator, nextMethod);
//得到getKey方法
jmethodID getKeyMethod = env->GetMethodID(jclass_of_mapentry, "getKey", "()Ljava/lang/Object;");
//得到getValue方法
jmethodID getValueMethod = env->GetMethodID(jclass_of_mapentry, "getValue", "()Ljava/lang/Object;");
jstring js_keyStr=(jstring)env->CallObjectMethod(jobject_of_Entry,getKeyMethod);
jstring js_value=(jstring)env->CallObjectMethod(jobject_of_Entry,getValueMethod);
std::string c_key=JniHelper::jstring2string(js_keyStr);
CCString *ccValue=CCStringMake(JniHelper::jstring2string(js_value));
dataDic->setObject(ccValue, c_key);
bHasNext=env->CallBooleanMethod(jobject_of_iterator, hasNextMethod);
//删除引用
env->DeleteLocalRef(js_value);
env->DeleteLocalRef(js_keyStr);
env->DeleteLocalRef(jobject_of_Entry);
env->DeleteLocalRef(jclass_of_mapentry);
}
//删除引用
env->DeleteLocalRef(jclass_of_iterator);
env->DeleteLocalRef(jobject_of_iterator);
env->DeleteLocalRef(jclass_of_set);
env->DeleteLocalRef(jobject_of_entryset);
env->DeleteLocalRef(jclass_of_hashmap);
}
const char* cnotifiName = env->GetStringUTFChars(notificaitonName, NULL);
CCLog("android send Notification::%s",cnotifiName);
CCNotificationCenter::sharedNotificationCenter()->postNotification(cnotifiName, dataDic);
env->ReleaseStringUTFChars(notificaitonName, cnotifiName);
env->DeleteLocalRef(notificaitonName);
}
}
这样子就可以在android代码里面很方便的传递数据到 c++层。 c++层接收到数据,发送一个通知给需要接收到数据,只需要写一个native方法就可以了。
这个代码是android到cocos2dx的,还没有实现cocos2dx 到android的通知转换,那位朋友有思路可以交流下。