See: https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JavaObject.cs#L35
The problem with new JavaObject(obj).Handle is that there is a window wherein the JavaObject is collected after the .Handle property is accessed, but before .Handle is returned to Java code, which would "normally" keep the JavaObject instance alive.
Related:
This statement should instead be:
return JNIEnv.ToLocalJniHandle (new JavaObject (obj));
Additionally, JNIEnv.ToLocalJniHandle() needs to add a GC.KeepAlive(): https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JNIEnv.cs#L746-L754
It should be:
public static IntPtr ToLocalJniHandle (IJavaObject? value)
{
if (value == null)
return IntPtr.Zero;
var ex = value as IJavaObjectEx;
if (ex != null)
return ex.ToLocalJniHandle ();
try {
return NewLocalRef (value.Handle);
}
finally {
GC.KeepAlive (value);
}
}
This will ensure that value isn't likewise GC'd immediately after the .Handle access but before NewLocalRef() is invoked.
See: https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JavaObject.cs#L35
The problem with
new JavaObject(obj).Handleis that there is a window wherein theJavaObjectis collected after the.Handleproperty is accessed, but before.Handleis returned to Java code, which would "normally" keep theJavaObjectinstance alive.Related:
This statement should instead be:
Additionally,
JNIEnv.ToLocalJniHandle()needs to add aGC.KeepAlive(): https://github.com/xamarin/xamarin-android/blob/f495778d433e45fee2fb61435293f059d6942620/src/Mono.Android/Android.Runtime/JNIEnv.cs#L746-L754It should be:
This will ensure that
valueisn't likewise GC'd immediately after the.Handleaccess but beforeNewLocalRef()is invoked.