public override IJavaPeerable PeekPeer(JniObjectReference reference) { if (!reference.IsValid) { return(null); } var hash = JNIEnv.IdentityHash(reference.Handle); lock (instances) { IdentityHashTargets targets; if (instances.TryGetValue(hash, out targets)) { for (int i = targets.Count - 1; i >= 0; i--) { var wref = targets [i]; if (!wref.TryGetTarget(out var result) || !result.PeerReference.IsValid) { targets.RemoveAt(i); continue; } if (!JniEnvironment.Types.IsSameObject(reference, result.PeerReference)) { continue; } return(result); } } } return(null); }
internal void AddPeer(IJavaPeerable value, IntPtr handle, JniHandleOwnership transfer, out IntPtr handleField) { if (handle == IntPtr.Zero) { handleField = handle; return; } var transferType = transfer & (JniHandleOwnership.DoNotTransfer | JniHandleOwnership.TransferLocalRef | JniHandleOwnership.TransferGlobalRef); switch (transferType) { case JniHandleOwnership.DoNotTransfer: handleField = JNIEnv.NewGlobalRef(handle); break; case JniHandleOwnership.TransferLocalRef: handleField = JNIEnv.NewGlobalRef(handle); JNIEnv.DeleteLocalRef(handle); break; case JniHandleOwnership.TransferGlobalRef: handleField = handle; break; default: throw new ArgumentOutOfRangeException("transfer", transfer, "Invalid `transfer` value: " + transfer + " on type " + value.GetType()); } if (handleField == IntPtr.Zero) { throw new InvalidOperationException("Unable to allocate Global Reference for object '" + value.ToString() + "'!"); } IntPtr hash = JNIEnv.IdentityHash(handleField); value.SetJniIdentityHashCode((int)hash); if ((transfer & JniHandleOwnership.DoNotRegister) == 0) { AddPeer(value, new JniObjectReference(handleField, JniObjectReferenceType.Global), hash); } if (Logger.LogGlobalRef) { JNIEnv._monodroid_gref_log("handle 0x" + handleField.ToString("x") + "; key_handle 0x" + hash.ToString("x") + ": Java Type: `" + JNIEnv.GetClassNameFromInstance(handleField) + "`; " + "MCW type: `" + value.GetType().FullName + "`\n"); } }
public override void RemovePeer(IJavaPeerable value) { if (value == null) { throw new ArgumentNullException(nameof(value)); } if (!value.PeerReference.IsValid) { throw new ArgumentException("Must have a valid JNI object reference!", nameof(value)); } var reference = value.PeerReference; var hash = JNIEnv.IdentityHash(reference.Handle); RemovePeer(value, hash); }