//        public TReturnType ObjectCall<TReturnType>(string name, params object[] args) {
//            Debug.LogWarning("ObjectCall1: " + name);
//            string sig = GetSignature<TReturnType>(args);
//            Debug.LogWarning("ObjectCall2: " + name + " => " + sig);
//            IntPtr methodId = AndroidJNIHelper.GetMethodID(RawClass, name, sig, false);
//
//            jvalue[] jArgs = ConstructArgArray(args);
//            try {
//                IntPtr val = JNISafe.CallObjectMethod(RawObject, methodId, jArgs);
//
//                if (val.Equals(IntPtr.Zero)) {
//                    return default(TReturnType);
//                }
//
//                var t = typeof(TReturnType);
//                if (t.IsSubclassOf(typeof(JavaObject))) {
//                    ConstructorInfo c = t.GetConstructor(new[] { val.GetType() });
//                    if (c != null) {
//                        return (TReturnType)c.Invoke(new object[] { val });
//                    }
//                }
//            }
//            finally {
//                AndroidJNIHelper.DeleteJNIArgArray(args, jArgs);
//            }
//
//            return default(TReturnType);
//        }

        public IntPtr ObjectCall(string name, string className, params object[] args)
        {
            string sig      = GetSignature(className, args);
            IntPtr methodId = AndroidJNIHelper.GetMethodID(RawClass, name, sig, false);

            jvalue[] jArgs = ConstructArgArray(args);
            try {
                IntPtr val = JNISafe.CallObjectMethod(RawObject, methodId, jArgs);

                if (val.Equals(IntPtr.Zero))
                {
                    return(IntPtr.Zero);
                }

                return(val);
            }
            finally {
                AndroidJNIHelper.DeleteJNIArgArray(args, jArgs);
            }
        }
        /// <summary>
        /// Calls a class method.
        ///
        /// <para>
        /// NOTE: be sure you passing correct type (it shoud be the primitive or the type derived from <see cref="JavaObject"/>)!
        /// </para>
        ///
        /// </summary>
        /// <returns>The invoke call.</returns>
        /// <param name="name">Method name.</param>
        /// <param name="args">Arguments.</param>
        /// <typeparam name="TReturnType"></typeparam>
        public TReturnType Call <TReturnType>(string name, params object[] args)
        {
            Type   t        = typeof(TReturnType);
            string sig      = GetSignature <TReturnType>(args);
            IntPtr methodId = AndroidJNIHelper.GetMethodID(RawClass, name, sig, false);

            jvalue[] jArgs = ConstructArgArray(args);
            try {
                if (methodId == IntPtr.Zero)
                {
                    Debug.LogError("Cannot get method for " + name);

                    throw new Exception("Cannot get method for " + name);
                }
                if (AndroidReflection.IsPrimitive(t))
                {
                    if (t == typeof(bool))
                    {
                        return((TReturnType)(object)JNISafe.CallBooleanMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(int))
                    {
                        return((TReturnType)(object)JNISafe.CallIntMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(float))
                    {
                        return((TReturnType)(object)JNISafe.CallFloatMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(double))
                    {
                        return((TReturnType)(object)JNISafe.CallDoubleMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(byte))
                    {
                        return((TReturnType)(object)JNISafe.CallByteMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(char))
                    {
                        return((TReturnType)(object)JNISafe.CallCharMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(long))
                    {
                        return((TReturnType)(object)JNISafe.CallLongMethod(RawObject, methodId, jArgs));
                    }
                    if (t == typeof(short))
                    {
                        return((TReturnType)(object)JNISafe.CallShortMethod(RawObject, methodId, jArgs));
                    }
                }

                if (t == typeof(string))
                {
                    return((TReturnType)(object)JNISafe.CallStringMethod(RawObject, methodId, jArgs));
                }

                if (t.IsSubclassOf(typeof(JavaObject)))
                {
                    IntPtr val = JNISafe.CallObjectMethod(RawObject, methodId, jArgs);

                    if (val == IntPtr.Zero)
                    {
                        return(default(TReturnType));
                    }

                    ConstructorInfo c = t.GetConstructor(new[] { val.GetType() });

                    if (c != null)
                    {
                        return((TReturnType)c.Invoke(new object[] { val }));
                    }
                    else
                    {
                        DebugPrint("Can't instantiate class, probably no constructor with IntPtr arg");
                    }
                }
            }
            finally {
                AndroidJNIHelper.DeleteJNIArgArray(args, jArgs);
            }

            return(default(TReturnType));
        }