【问题标题】:How to send cocos2d ValueMap to Java as HashMap?如何将 cocos2d ValueMap 作为 HashMap 发送到 Java?
【发布时间】:2017-10-11 08:55:37
【问题描述】:

我有cocos2d:: ValueMap:

 ValueMap map;
 map["key1"] = "value1";
 map["key2"] = 1;
 map["key3"] = true;

我想以HashMap<String,Object>

将其发送到 Java

所以我编写了以下代码,在其中生成jobject hashMapObj,我想用值填充它:

jclass hashMapClass= jniGetInstance.env->FindClass("java/util/HashMap");
jmethodID hashMapInit = jniGetInstance.env->GetMethodID(hashMapClass, "<init>", "(I)V");
jobject hashMapObj = jniGetInstance.env->NewObject(hashMapClass, hashMapInit, values.size());

//javap -s -p java.util.HashMap  | grep -A 1 put\(
jmethodID hashMapId = jniGetInstance.env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");

for (auto it : map) {   //https://github.com/cocos2d/cocos2d-x/blob/v3/cocos/base/CCValue.h
    switch (it.second.getType()) {
        case cocos2d::Value::Type::BOOLEAN:
            jniGetInstance.env->CallObjectMethod(hashMapObj, hashMapId, "put",
                                                 jniGetInstance.env->NewStringUTF(
                                                         it.first.c_str()),
                                                 it.second.asBool());
            break;
       //...

        default:
            break;
    }
}

我在排队时遇到了崩溃:

jniGetInstance.env->CallObjectMethod(
   hashMapObj, 
   hashMapId,
   "put", 
   jniGetInstance.env->NewStringUTF(                                             
               it.first.c_str()),
               it.second.asBool());

在应用程序中检测到 JNI 错误:使用了无效的 jobject 0xd85d4aa0

编辑

jniGetInstance.env->CallObjectMethod(hashMapObj, hashMapId, "put","someString", true);

失败并出现同样的错误,所以问题出在hashMapObj

有什么想法吗?

【问题讨论】:

  • 只是想知道为什么不将它作为 JSON 字符串发送,以便您可以将其打包到 java 中的 HashMap...
  • @RRTW 因为在 Java 端我有只接收 HashMap 的 API
  • boolean 是否与 java.lang.Boolean 相同? boolean 是一个对象吗?任何原始数据类型都是对象吗? ...您是否尝试创建并放在那里java.lang.Boolean
  • 以 JSON 格式发送,新建一个 JavaAPI 将其打包为 HashMap,并将其传递给您现有的仅 HashMap API,我认为这是最快速且风险最低的方式。

标签: java android c++ cocos2d-x


【解决方案1】:

改变

jniGetInstance.env->CallObjectMethod(hashMapObj, hashMapId, "put",
    jniGetInstance.env->NewStringUTF(
        it.first.c_str()),
        it.second.asBool());

jniGetInstance.env->CallObjectMethod(hashMapObj, hashMapId,
    jniGetInstance.env->NewStringUTF(it.first.c_str()),
    it.second.asBool());

因为“put”方法只接受 2 个参数。

还要确保 it.second.asBool() 返回 jboolean - 它不同于 C++ bool 类型。

【讨论】:

  • 是的,这是有道理的,但是它仍然失败并出现错误:JNI ERROR (app bug): attempt to use stale Local 0x1 (should be 0x9) 10-11 15:15:33.662 28123-28540/com.snaggs.cocos2dX A/zygote: java_vm_ext.cc:504] JNI DETECTED ERROR IN APPLICATION: use of deleted local reference 0x1
  • 那么您可能需要将it.second.asBool() 包装到Boolean java 对象中。使用后不要忘记为本地创建的所有对象(HashMapStringBoolean)调用 DeleteLocalRef
  • 是的,我知道,也许 HashMap 期望 java/lang/Object?我试过直接写:jniGetInstance.env-&gt;CallObjectMethod(hashMapObj, hashMapId,"xxx","ssss"); 但还是失败了JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0xd86d1af0
  • 你说得对,这个有效:jniGetInstance.env-&gt;CallObjectMethod(hashMapObj, hashMapId,jniGetInstance.env-&gt;NewStringUTF("xxx"),jniGetInstance.env-&gt;NewStringUTF("ssss"));
  • "xxx" 和 "ssss" 不是 java 对象,只是字符串文字。要创建对象,您需要使用函数 NewStringUTFNewObject
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2020-09-22
相关资源
最近更新 更多