Search code examples
c#unity-game-enginexamarin.androidmono

create java hashmap with Unity AndroidJavaObject


I have a method in my java library that gets a Map as an input.
here is my java method

public void myMethod(Map<String, String> map){
    //do some thing with this map
}

And my C# code in Unity

AndroidJavaObject javaMap= new AndroidJavaObject("java.util.HashMap");
javaMap.Call("put", "key1", "value1");
AndroidJavaClass javaClass = new AndroidJavaClass("com.alirezaahmadi.android.sdk.core.BaseAPI");
javaClass.CallStatic("myMethod", javaMap);

I can try some code like this but Map is a generic class and this code doesn't work

when i run this i get this error

AndroidJavaException: java.lang.NoSuchMethodError: no non-static method with name='put' signature='(Ljava/lang/String;Ljava/lang/String;)V' in class Ljava.lang.Object;
java.lang.NoSuchMethodError: no non-static method with name='put' signature='(Ljava/lang/String;Ljava/lang/String;)V' in class Ljava.lang.Object;

How can i fix this and path a java hashmap to this method. BTW I can not change the java code.


Solution

  • After hours of trying I found this code to convert my C# dictainary to AndroidJavaObject HashMap

    public static AndroidJavaObject CreateJavaMapFromDictainary(IDictionary<string, string> parameters)
    {
        AndroidJavaObject javaMap = new AndroidJavaObject("java.util.HashMap");
        IntPtr putMethod = AndroidJNIHelper.GetMethodID(
            javaMap.GetRawClass(), "put",
                "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    
        object[] args = new object[2];
        foreach (KeyValuePair<string, string> kvp in parameters)
        {
    
            using (AndroidJavaObject k = new AndroidJavaObject(
                "java.lang.String", kvp.Key))
            {
                using (AndroidJavaObject v = new AndroidJavaObject(
                    "java.lang.String", kvp.Value))
                {
                    args[0] = k;
                    args[1] = v;
                    AndroidJNI.CallObjectMethod(javaMap.GetRawObject(),
                            putMethod, AndroidJNIHelper.CreateJNIArgArray(args));
                }
            }
        }
    
        return javaMap;
    }
    

    Then i simply call my method and path the map like this

    AndroidJavaObject javaMap = CreateJavaMapFromDictainary(myDictainry);
    AndroidJavaClass javaClass = new AndroidJavaClass("com.alirezaahmadi.android.sdk.core.BaseAPI");
    javaClass.CallStatic("myMethod", javaMap);