public void Construct(IJavaPeerable peer, ref JniObjectReference reference, JniObjectReferenceOptions options) { if (peer == null) { throw new ArgumentNullException(nameof(peer)); } var newRef = peer.PeerReference; if (newRef.IsValid) { // Activation! See ManagedPeer.RunConstructor peer.SetJniManagedPeerState(peer.JniManagedPeerState | JniManagedPeerStates.Activatable); JniObjectReference.Dispose(ref reference, options); newRef = newRef.NewGlobalRef(); } else if (options == JniObjectReferenceOptions.None) { // `reference` is likely *InvalidJniObjectReference, and can't be touched return; } else if (!reference.IsValid) { throw new ArgumentException("JNI Object Reference is invalid.", nameof(reference)); } else { newRef = reference; if ((options & JniObjectReferenceOptions.Copy) == JniObjectReferenceOptions.Copy) { newRef = reference.NewGlobalRef(); } JniObjectReference.Dispose(ref reference, options); } peer.SetPeerReference(newRef); peer.SetJniIdentityHashCode(JniSystem.IdentityHashCode(newRef)); var o = Runtime.ObjectReferenceManager; if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Created PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3}, Java.Type={4}", newRef.ToString(), peer.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(peer).ToString("x"), peer.GetType().FullName, JniEnvironment.Types.GetJniTypeNameFromInstance(newRef)); } if ((options & DoNotRegisterTarget) != DoNotRegisterTarget) { Add(peer); } }
internal static IJavaPeerable CreateInstance(IntPtr handle, JniHandleOwnership transfer, Type targetType) { Type type = null; IntPtr class_ptr = JNIEnv.GetObjectClass(handle); string class_name = GetClassName(class_ptr); lock (TypeManagerMapDictionaries.AccessLock) { while (class_ptr != IntPtr.Zero && !TypeManagerMapDictionaries.JniToManaged.TryGetValue(class_name, out type)) { type = GetJavaToManagedType(class_name); if (type != null) { TypeManagerMapDictionaries.JniToManaged.Add(class_name, type); break; } IntPtr super_class_ptr = JNIEnv.GetSuperclass(class_ptr); JNIEnv.DeleteLocalRef(class_ptr); class_ptr = super_class_ptr; class_name = GetClassName(class_ptr); } } JNIEnv.DeleteLocalRef(class_ptr); if (type == null) { JNIEnv.DeleteRef(handle, transfer); throw new NotSupportedException( string.Format("Internal error finding wrapper class for '{0}'. (Where is the Java.Lang.Object wrapper?!)", JNIEnv.GetClassNameFromInstance(handle)), CreateJavaLocationException()); } if (targetType != null && !targetType.IsAssignableFrom(type)) { type = targetType; } if (type.IsInterface || type.IsAbstract) { var invokerType = JavaObjectExtensions.GetHelperType(type, "Invoker"); if (invokerType == null) { throw new NotSupportedException("Unable to find Invoker for type '" + type.FullName + "'. Was it linked away?", CreateJavaLocationException()); } type = invokerType; } IJavaPeerable result = null; try { result = (IJavaPeerable)CreateProxy(type, handle, transfer); if (Runtime.IsGCUserPeer(result.PeerReference.Handle)) { result.SetJniManagedPeerState(JniManagedPeerStates.Replaceable); } } catch (MissingMethodException e) { var key_handle = JNIEnv.IdentityHash(handle); JNIEnv.DeleteRef(handle, transfer); throw new NotSupportedException( string.Format("Unable to activate instance of type {0} from native handle 0x{1} (key_handle 0x{2}).", type, handle.ToString("x"), key_handle.ToString("x")), e); } return(result); }