Android: Fix crash when emitting signal with java.util.HashMap

This commit is contained in:
Anish Kumar committed 2026-03-17 22:55:18 +05:30
1 parent 634220e9fc
commit 5387f0d596
3 files changed
+53 -15

No files matched your search

@@ -31,11 +31,16 @@
package org.godotengine.godot;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Dictionary extends HashMap<String, Object> {
protected String[] keys_cache;
public final class Dictionary extends HashMap<String, Object> {
private String[] keys_cache;
/**
* @deprecated Use {@link java.util.HashMap#keySet()} instead.
*/
@Deprecated
public String[] get_keys() {
String[] ret = new String[size()];
int i = 0;
@@ -48,6 +53,10 @@ public class Dictionary extends HashMap<String, Object> {
return ret;
}
/**
* @deprecated Use {@link java.util.HashMap#values()} instead.
*/
@Deprecated
public Object[] get_values() {
Object[] ret = new Object[size()];
int i = 0;
@@ -60,10 +69,18 @@ public class Dictionary extends HashMap<String, Object> {
return ret;
}
/**
* @deprecated Use {@link java.util.HashMap#putAll(Map)} instead.
*/
@Deprecated
public void set_keys(String[] keys) {
keys_cache = keys;
}
/**
* @deprecated Use {@link java.util.HashMap#putAll(Map)} instead.
*/
@Deprecated
public void set_values(Object[] vals) {
int i = 0;
for (String key : keys_cache) {
+2 -2
View File
@@ -1078,7 +1078,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
if (java_class_wrapped.is_valid()) {
String cn = java_class_wrapped->get_java_class_name();
if (cn == "org.godotengine.godot.Dictionary" || cn == "java.util.HashMap") {
if (cn == "org.godotengine.godot.Dictionary") {
var = _jobject_to_variant(env, obj);
} else {
Ref<JavaObject> ret = Ref<JavaObject>(memnew(JavaObject(java_class_wrapped, obj)));
@@ -1442,7 +1442,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
if (java_class_wrapped.is_valid()) {
String cn = java_class_wrapped->get_java_class_name();
if (cn == "org.godotengine.godot.Dictionary" || cn == "java.util.HashMap") {
if (cn == "org.godotengine.godot.Dictionary") {
ret[i] = _jobject_to_variant(env, obj);
} else {
Ref<JavaObject> java_obj_wrapped = Ref<JavaObject>(memnew(JavaObject(java_class_wrapped, obj)));
+32 -11
View File
@@ -428,25 +428,46 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj, int p_depth) {
return varr;
}
if (name == "java.util.HashMap" || name == "org.godotengine.godot.Dictionary") {
if (name == "org.godotengine.godot.Dictionary") {
Dictionary ret;
jclass oclass = c;
jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys);
PackedStringArray keys = _jobject_to_variant(env, arr, p_depth + 1);
env->DeleteLocalRef(arr);
jmethodID entrySet = env->GetMethodID(oclass, "entrySet", "()Ljava/util/Set;");
jobject entrySetObj = env->CallObjectMethod(obj, entrySet);
jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;");
arr = (jobjectArray)env->CallObjectMethod(obj, get_values);
jclass setClass = env->GetObjectClass(entrySetObj);
jmethodID iterator = env->GetMethodID(setClass, "iterator", "()Ljava/util/Iterator;");
jobject iteratorObj = env->CallObjectMethod(entrySetObj, iterator);
Array vals = _jobject_to_variant(env, arr, p_depth + 1);
env->DeleteLocalRef(arr);
jclass iteratorClass = env->GetObjectClass(iteratorObj);
jmethodID hasNext = env->GetMethodID(iteratorClass, "hasNext", "()Z");
jmethodID next = env->GetMethodID(iteratorClass, "next", "()Ljava/lang/Object;");
for (int i = 0; i < keys.size(); i++) {
ret[keys[i]] = vals[i];
jclass entryClass = jni_find_class(env, "java/util/Map$Entry");
jmethodID getKey = env->GetMethodID(entryClass, "getKey", "()Ljava/lang/Object;");
jmethodID getValue = env->GetMethodID(entryClass, "getValue", "()Ljava/lang/Object;");
while (env->CallBooleanMethod(iteratorObj, hasNext)) {
jobject entry = env->CallObjectMethod(iteratorObj, next);
jobject jkey = env->CallObjectMethod(entry, getKey);
jobject jvalue = env->CallObjectMethod(entry, getValue);
Variant key = _jobject_to_variant(env, jkey, p_depth + 1);
Variant value = _jobject_to_variant(env, jvalue, p_depth + 1);
ret[key] = value;
env->DeleteLocalRef(entry);
env->DeleteLocalRef(jkey);
env->DeleteLocalRef(jvalue);
}
env->DeleteLocalRef(entrySetObj);
env->DeleteLocalRef(iteratorObj);
env->DeleteLocalRef(setClass);
env->DeleteLocalRef(iteratorClass);
env->DeleteLocalRef(entryClass);
return ret;
}