System.ArgumentException'jobobject' 不得为 IntPtr.Zero。参数名称:jobobject

2024-03-12

我收到一个错误,我无法理解:

我在 void 方法中有这个简单的警报对话框生成器

private void startAction() {
                AlertDialog.Builder builder;
                builder = new AlertDialog.Builder (this);
                var ad = builder.Create ();
                builder.SetMessage ("Some text");
                builder.SetPositiveButton ("OK", delegate { 
                    ad.Dismiss ();
                    ShowDialog (0);
                });
                builder.SetNegativeButton ("Cancel", delegate { 
                    ad.Cancel ();
                });
                builder.SetCancelable (true);                    
                builder.Show ();
}

Xamarin Insights 向我展示了一份崩溃报告(多次),我既无法重现也无法理解。

System.ArgumentException'jobject' must not be IntPtr.Zero. Parameter name: jobject
Raw
Android.Runtime.JNIEnv.CallVoidMethod(IntPtr jobject, IntPtr jmethod)
Android.App.Dialog.Dismiss()
SpoonacularApp.Droid.ShoppingListActivity.<startAction>c__AnonStorey3.<>m__0(object, DialogClickEventArgs)
Android.Content.IDialogInterfaceOnClickListenerImplementor.OnClick(IDialogInterface dialog, int which)
Android.Content.IDialogInterfaceOnClickListenerInvoker.n_OnClick_Landroid_content_DialogInterface_I(IntPtr jnienv, IntPtr native__this, IntPtr native_dialog, int which)
at (wrapper dynamic-method) System.Object:ba5962df-899a-46fd-a4bd-6c9ffe426b75 (intptr,intptr,intptr,int)

这个例外讨论的是哪一个论点?

我收到了同样的错误消息Android.App.Dialog.Cancel()代替Android.App.Dialog.Dismiss() too.


The 对等连接 https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/#Cross-VM_Object_Collections for AlertDialog ad;已被切断;虽然该对象在 .NET 中仍然可用(通过单击处理程序),但它的 Java 对应项已被收集。这两个对象之间的绑定保存在存储在IntPtr Handle.NET 中所有实现的对象的属性IJavaObject.

当跨VM收集周期发生时,Handle被设定为IntPtr.Zero并释放全局Java引用,使Dalvik(Java)能够收集Java对象。

您看到此崩溃是因为应用程序可能已进入后台并且 Android 已触发应用程序进程的收集。这导致大多数 Java 资源被 Dalvik 垃圾收集器销毁,但它们相应的 .NET 对象仍然存在,并且现在指向无效的 Java 对象。

解决此问题的方法是检查两个单击处理程序内的对等连接AlertDialog使用以下代码片段 https://gist.github.com/matthewrdev/a89546ae3c5e267d9519:

public static class PeerConnectionHelper
{
    public static bool HasPeerConnection(Java.Lang.Object jObj)
    {
        return !(jObj == null || jObj.Handle == System.IntPtr.Zero);
    }

    public static bool HasPeerConnection (Android.Runtime.IJavaObject jObj)
    {
        return !(jObj == null || jObj.Handle == System.IntPtr.Zero);
    }
}

这将像这样实现:

builder.SetPositiveButton ("OK", delegate { 
    if (!PeerConnectionHelper.HasPeerConnection(ad)) {
        return;
    }

    ad.Dismiss ();
    ShowDialog (0);
});
builder.SetNegativeButton ("Cancel", delegate { 
    if (!PeerConnectionHelper.HasPeerConnection(ad)) {
        return;
    }

    ad.Cancel ();
});

更多阅读:

  • Xamarin.Android GC 文档 https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/
  • 对等连接崩溃的修复示例 https://github.com/matthewrdev/xamarin-samples/tree/master/xamarin-android-memory-management-gotchas
  • Xamarin.Android 内存管理陷阱 http://www.slideshare.net/AlecTucker/xamarinandroid-memory-management-gotchas
  • 关于 Xamarin.Android 终结器和对等连接的讨论 https://stackoverflow.com/questions/28863058/xamarin-android-finalizer-not-getting-called-when-leaving-the-activity-to-go-to/28868582#28868582
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

System.ArgumentException'jobobject' 不得为 IntPtr.Zero。参数名称:jobobject 的相关文章

随机推荐