Skip to content

Instantly share code, notes, and snippets.

@matthewrdev
Last active November 15, 2021 23:59
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save matthewrdev/a89546ae3c5e267d9519 to your computer and use it in GitHub Desktop.
Save matthewrdev/a89546ae3c5e267d9519 to your computer and use it in GitHub Desktop.
Utility class to detect severed peer connections in Xamarin.Android.
/// <summary>
/// Helper class to detect when .NET objects with a Java peer object have been "severed".
/// <para/>
/// Peer objects are .NET types which implement IJavaObject , e.g. all Java.Lang.Object and Java.Lang.Throwable subclasses.
/// Instances of these types have two "halfs" a managed peer and a native peer.
/// <list type="bullet">
/// <item>The managed peer is an instance of the C# class.</item>
/// <item>The native peer is an instance of a Java class within the Android runtime VM, and the C# IJavaObject.Handle property contains a JNI global reference to the native peer.</item>
/// </list>
/// There are two types of native peers:
/// <list type="bullet">
/// <item>Framework peers : "Normal" Java types which know nothing of Xamarin.Android, e.g. android.content.Context .</item>
/// <item>User peers : Android Callable Wrappers which are generated at build time for each Java.Lang.Object subclass present within the application.</item>
/// </list>
/// Invoking methods that interop into Java on a .NET object with no peer connection results in a "System.ArgumentException: 'jobject' must not be IntPtr.Zero" exception.
/// As the .NET objects `Handle` (that points to the peer connection) has been zeroed when the connection was broken, no Java object exists for the interop method to invoke against.
/// <para/>
/// Read more about peer connections at:
/// https://docs.microsoft.com/en-au/xamarin/android/internals/garbage-collection#Cross-VM_Object_Collections
/// </summary>
public static class PeerConnectionHelper
{
/// <summary>
/// Determines if the Java Object has a corresponding peer object.
/// </summary>
/// <returns><c>true</c> If jObj has a Dalvik peer object, false if the peer connection has been severed.<c>false</c>.</returns>
/// <param name="jObj">A Java.Lang.Object object.</param>
public static bool HasPeerConnection(Java.Lang.Object jObj)
{
return !(jObj == null || jObj.Handle == System.IntPtr.Zero);
}
/// <summary>
/// Determines if the implementation of IJavaObject has a corresponding peer object.
/// </summary>
/// <returns><c>true</c> If jObj has a Dalvik peer object, false if the peer connection has been severed.<c>false</c>.</returns>
/// <param name="jObj">A object that implements Android.Runtime.IJavaObject.</param>
public static bool HasPeerConnection (Android.Runtime.IJavaObject jObj)
{
return !(jObj == null || jObj.Handle == System.IntPtr.Zero);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment