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"); } }