diff --git a/external/Java.Interop b/external/Java.Interop index 6bbb00aa3fd..007b35b4891 160000 --- a/external/Java.Interop +++ b/external/Java.Interop @@ -1 +1 @@ -Subproject commit 6bbb00aa3fdfdb61f3b5167b6bb025f62a54ccdf +Subproject commit 007b35b489173010de038c95cb2a0d3ec514f30d diff --git a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs index 6c3f738c244..d989036b95e 100644 --- a/src/Mono.Android/Android.Runtime/AndroidRuntime.cs +++ b/src/Mono.Android/Android.Runtime/AndroidRuntime.cs @@ -558,10 +558,12 @@ 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; + if (!reference.IsValid) { + // Likely an idempotent DIspose(); ignore. + return; + } var hash = JNIEnv.IdentityHash! (reference.Handle); RemovePeer (value, hash); diff --git a/src/Mono.Android/Test/Java.Lang/ObjectTest.cs b/src/Mono.Android/Test/Java.Lang/ObjectTest.cs index 9eb8421d2f1..302ef9b2ac5 100644 --- a/src/Mono.Android/Test/Java.Lang/ObjectTest.cs +++ b/src/Mono.Android/Test/Java.Lang/ObjectTest.cs @@ -67,6 +67,14 @@ public void JnienvCreateInstance_RegistersMultipleInstances () Assert.AreSame (adapter, registered); } } + + [Test] + public void NestedDisposeInvocations () + { + var value = new MyDisposableObject (); + value.Dispose (); + value.Dispose (); + } } /* @@ -157,4 +165,23 @@ public override void SetSelection (int position) throw new NotImplementedException(); } } + + public class MyDisposableObject : Java.Lang.Object + { + bool _isDisposed; + public MyDisposableObject () + { + } + + protected override void Dispose (bool disposing) + { + if (_isDisposed) { + return; + } + _isDisposed = true; + if (this.Handle != IntPtr.Zero) + this.Dispose (); + base.Dispose (disposing); + } + } }