1

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.

4
  • Don't you think it would be useful to post your Java code as well so that we can see the myMethod method? Maybe tell us which line of from the C# is causing the error. With what you have now there is no way one can figure out your problem. Commented Jul 11, 2017 at 12:55
  • In addition to the "myMethod" method, AndroidJavaObject.Call() takes a method as its first input, which in your case would be "put". It is not apparent whether or not this method exists from your explanation - which should solve your problem if it does not. Commented Jul 11, 2017 at 12:59
  • 1
    @ryemoss I'm trying to create a java map. error will be rise in line 2 when I call put method of Java Map class. The problem is Map class is generic and put takes generic arguments not just strings. Commented Jul 11, 2017 at 13:54
  • How to write a reverse function? convertMapToDictionary Commented Aug 22, 2019 at 13:16

2 Answers 2

3

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);
Sign up to request clarification or add additional context in comments.

1 Comment

In case anyone wants to use this with a string, object hashmap. They should be very careful with assuming that the value is always 'compatible' with the new String() java constructor arguments - e.g. Object is not valid, neither is many array types. To make the code handle more types you should use the static String.valueOf - it does handle arrays and objects. Like this . var stringClazz = new AndroidJavaClass("java.lang.String"); var value = stringClazz.CallStatic<string>("valueOf", kvp.Value);
1

Here's a simplified version of Reza's solution that I use:

public AndroidJavaObject ConvertDictionaryToJavaMap(Dictionary<string, string> dictionary) {

    AndroidJavaObject map = new AndroidJavaObject("java.util.HashMap");
    IntPtr putMethod = AndroidJNIHelper.GetMethodID(map.GetRawClass(), "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
    foreach (var entry in dictionary) {
        AndroidJNI.CallObjectMethod(
            map.GetRawObject(),
            putMethod,
            AndroidJNIHelper.CreateJNIArgArray(new object[] { entry.Key, entry.Value })
        );
    }
    return map;
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.