internal static void AssertSelf(IJavaPeerable self) { if (self == null) { throw new ArgumentNullException(nameof(self)); } var peer = self.PeerReference; if (!peer.IsValid) { throw new ObjectDisposedException(self.GetType().FullName); } #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var lref = peer.SafeHandle as JniLocalReference; if (lref != null && !JniEnvironment.IsHandleValid(lref)) { var t = self.GetType().FullName; throw new NotSupportedException( "You've created a " + t + " in one thread and are using it " + "from another thread without calling IJavaPeerable.Register(). " + "Passing JNI local references between threads is not supported; " + "call IJavaObject.RegisterWithVM() if sharing between threads is required."); } #endif // FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES }
void Dispose(JniObjectReference h, IJavaPeerable value) { value.Disposed(); Remove(value); var o = Runtime.ObjectReferenceManager; if (o.LogGlobalReferenceMessages) { o.WriteGlobalReferenceLine("Disposing PeerReference={0} IdentityHashCode=0x{1} Instance=0x{2} Instance.Type={3} Java.Type={4}", h.ToString(), value.JniIdentityHashCode.ToString("x"), RuntimeHelpers.GetHashCode(value).ToString("x"), value.GetType().ToString(), JniEnvironment.Types.GetJniTypeNameFromInstance(h)); } #if FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES var lref = value.PeerReference.SafeHandle as JniLocalReference; if (lref != null && !JniEnvironment.IsHandleValid(lref)) { // `lref` was created on another thread, and CANNOT be disposed on this thread. // Just invalidate the reference and move on. lref.SetHandleAsInvalid(); } #endif // FEATURE_JNIOBJECTREFERENCE_SAFEHANDLES JniObjectReference.Dispose(ref h); value.SetPeerReference(new JniObjectReference()); GC.SuppressFinalize(value); }