System.ArgumentException'jobject'不能是IntPtr.Zero。参数名称:jobject

时间:2016-01-02 23:40:04

标签: android xamarin

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

我在void方法中有这个简单的警告对话框构建器

/dev/urandom

Xamarin Insights向我展示了一份我无法复制或理解的崩溃报告。

beforeSend

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

我收到了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 (); } 而不是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) 的错误消息。

1 个答案:

答案 0 :(得分:6)

AlertDialog ad;的{​​{3}}已被切断;虽然该对象仍然可以在.NET中使用(通过点击处理程序),但它已经收集了它的Java对应物。这两个对象之间的绑定保存在存储在IntPtr Handle属性中的全局引用中,用于实现IJavaObject的.NET中的所有对象。

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

您已经看到此次崩溃,因为该应用可能已经落后,并且Android已触发应用流程的集合。这导致大多数Java资源被Dalviks垃圾收集器破坏,但它们相应的.NET对象仍处于活动状态,现在指向无效的Java对象。

对此的修复是使用peer connection检查AlertDialog的点击处理程序内的对等连接:

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 ();
});

更多阅读: