internal JavaClass(JniWrapper vm, IntPtr jniClass, IntPtr reflectedClass, string name) { _vm = vm; _classClass = new JClassClass(vm); _methodClass = new JMethodClass(vm); _fieldClass = new JFieldClass(vm); _constructorClass = new JConstructorClass(vm); _classLoaderClass = new JClassLoaderClass(vm); _jniClass = jniClass; _reflectedClass = reflectedClass; if (_reflectedClass == IntPtr.Zero) { if (name == null) { throw new ArgumentNullException("I can't infer the name from just the JNI class (I should be able to, but I have no idea how)."); } _reflectedClass = _classClass.ForName(name.Replace('/', '.'), true, _classLoaderClass.GetSystemClassLoader()); if (_reflectedClass == IntPtr.Zero) { ThrowClassNotFoundException(name); } } if (name == null) { name = _classClass.GetName(_reflectedClass); } if (_jniClass == IntPtr.Zero) { _jniClass = vm.FindClass(name.Replace('.', '/')); if (_jniClass == IntPtr.Zero) { ThrowClassNotFoundException(name); } } _name = name.Replace('/', '.'); _allMethods = _classClass.GetMethods(_reflectedClass).ToList().AsReadOnly(); _allConstructors = _classClass.GetConstructors(_reflectedClass).ToList().AsReadOnly(); }
private object InvokeMethod(IntPtr method, ParameterInfo[] parameterInfo, bool[] needBoxing) { object result; IntPtr methodReturn = _methodClass.GetReturnType(method); IntPtr jniMethodPtr = _vm.FromReflectedMethod(method); string returnTypeName = _classClass.GetName(methodReturn); JValue[] parameters = parameterInfo.Select((p, i) => p.Value(_vm, needBoxing[i])).ToArray(); PrimitiveType returnTypeAsPrimitive = PrimitiveType.FromString(_vm, returnTypeName); if (methodReturn == IntPtr.Zero || returnTypeName == "void") { result = null; _vm.CallVoidMethod(_objectPointer, jniMethodPtr, parameters); } else if (returnTypeAsPrimitive != null) { switch (returnTypeAsPrimitive.Kind) { case PrimitiveTypeKind.Boolean: result = _vm.CallBooleanMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Byte: result = _vm.CallByteMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Char: result = _vm.CallCharMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Double: result = _vm.CallDoubleMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Float: result = _vm.CallFloatMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Int: result = _vm.CallIntMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Long: result = _vm.CallLongMethod(_objectPointer, jniMethodPtr, parameters); break; case PrimitiveTypeKind.Short: result = _vm.CallShortMethod(_objectPointer, jniMethodPtr, parameters); break; default: throw new InvalidOperationException("Unknown primitive type: " + returnTypeAsPrimitive.Kind); } } else { IntPtr methodResult = _vm.CallObjectMethod(_objectPointer, jniMethodPtr, parameters); if (methodResult != IntPtr.Zero) { if (returnTypeName.StartsWith("[")) { result = new JavaArray(_vm, methodResult, (ArrayType)JavaType.FromReflectedType(_vm, methodReturn)); } else { result = new JavaObject(_vm, methodResult, null); } } else { result = null; } } return(result); }