Beispiel #1
0
            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 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");
            }
        }