使用MvxAdapter时的例外情况

时间:2014-08-21 00:50:46

标签: android listview xamarin mvvmcross

我有以下设置: 一个带有2个标签的应用。在第二个选项卡上有一个绑定到ObservableCollection的ListView。在第一个选项卡上有控件,导致第二个选项卡的ViewModel重新加载ObservableCollection。它运行良好,直到我添加了自定义MvxAdapter(需要它用于多态列表项)。在每次更新之后,我在应用程序输出中看到以下异常(请注意列表仍然重新加载其值):

    mvx:Warning: 42.24 Exception masked during Adapter RealNotifyDataSetChanged ArgumentException: 'jobject' must not be IntPtr.Zero.
Parameter name: jobject
      at Android.Runtime.JNIEnv.CallNonvirtualVoidMethod (IntPtr jobject, IntPtr jclass, IntPtr jmethod) [0x00010] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:866 
  at Android.Widget.BaseAdapter.NotifyDataSetChanged () [0x00058] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Widget.BaseAdapter.cs:311 
  at Cirrious.MvvmCross.Binding.Droid.Views.MvxAdapter.RealNotifyDataSetChanged () [0x00000] in <filename unknown>:0 
mvx:Warning: 42.24 Exception masked during Adapter RealNotifyDataSetChanged ArgumentException: 'jobject' must not be IntPtr.Zero.
Parameter name: jobject
      at Android.Runtime.JNIEnv.CallNonvirtualVoidMethod (IntPtr jobject, IntPtr jclass, IntPtr jmethod) [0x00010] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:866 
  at Android.Widget.BaseAdapter.NotifyDataSetChanged () [0x00058] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.14-series/8e79d361/source/monodroid/src/Mono.Android/platforms/android-19/src/generated/Android.Widget.BaseAdapter.cs:311 
  at Cirrious.MvvmCross.Binding.Droid.Views.MvxAdapter.RealNotifyDataSetChanged () [0x00000] in <filename unknown>:0 

我想知道是否有人可以帮助我找出抛出这些异常的原因。

public override View OnCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState)
    {
        base.OnCreateView(inflater, container, savedInstanceState);

        var view = this.BindingInflate(Resource.Layout.ChildPage_History, null);

        listView = view.FindViewById<MvxListView> (Resource.Id.history_list);

        listView.Adapter = new CustomAdapter (this.Activity, (IMvxAndroidBindingContext)BindingContext);

        return view;
    }

2 个答案:

答案 0 :(得分:5)

我认为问题是由MvxListView构造函数创建默认MvxAdapter引起的。创建绑定时,默认MvxAdapter订阅列表绑定的集合的集合已更改事件。但是,当MvxListView.Adapter设置为CustomAdapter时,原始MvxAdapter仍会订阅该集合。最后,原始的MvxAdapter被垃圾收集,所以当集合更改时,处理程序被调用处理器,并且显示的结果就是结果。

我通过派生自己的MvxListView解决了我的项目中的问题,该public class MyListView : MvxListView { public MyListView(Context context, IAttributeSet attrs) : base(context, attrs, new CustomAdapter(context)) { } } 覆盖了构造函数并返回了适配器,这意味着无需在OnCreateView中设置它:

MvxListView

只需将布局XML更改为使用此类而不是{{1}},异常应该停止。

答案 1 :(得分:1)

这是一个线程问题。您必须在正确的线程中引发源的属性更改。尝试在不同的项目中加载源,然后将其分配回列表中绑定的属性。