예제 #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);
                }
            }
예제 #2
0
        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);
        }