3

我正在与一个团队一起使用 MvvmCross 创建一个 android 应用程序。最近我们开始看到大量重复的警告/错误消息,看起来像这样:

MvxBind:Warning:207.06 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
[0:] MvxBind:Warning:207.06 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
09-05 17:56:25.076 I/MvxBind (20932): 207.06 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
09-05 17:56:25.086 I/mono-stdout(20932): MvxBind:Warning:207.06 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
[0:] 
MvxBind:Warning:207.08 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
[0:] MvxBind:Warning:207.08 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
09-05 17:56:25.096 I/MvxBind (20932): 207.08 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
09-05 17:56:25.096 I/mono-stdout(20932): MvxBind:Warning:207.08 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
[0:] 
09-05 17:56:25.116 I/MvxBind (20932): 207.10 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
MvxBind:Warning:207.10 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
[0:] MvxBind:Warning:207.10 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
09-05 17:56:25.126 I/mono-stdout(20932): MvxBind:Warning:207.10 Weak Target is null in MvxTextViewTextTargetBinding - skipping set
[0:] 
09-05 17:56:25.126 I/MvxBind (20932): 207.12 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
MvxBind:Warning:207.12 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
[0:] MvxBind:Warning:207.12 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set
09-05 17:56:25.136 I/mono-stdout(20932): MvxBind:Warning:207.12 Weak Target is null in MvxWithEventPropertyInfoTargetBinding - skipping set

这些消息在从显示 MvxGridView 的视图切换后大约 3 分钟开始。MvxGridview 绑定到一组视图模型,每个模型都有自己的绑定。消息一直持续到应用程序停止。消息一开始,用户界面就会变得越来越迟钝,并最终完全锁定。有趣的是,从该屏幕切换似乎是触发因素。我可以切换屏幕然后什么也不做,大约 3 分钟,大量消息将开始涌入。如果我将应用程序留在那个屏幕上,一切都会顺利进行。

最终,我只想知道如何解决问题,以便应用程序正常运行。可能有助于实现该目标的一些问题包括:

  1. 是否可以从 MvvmCross 获得更详细的堆栈跟踪?已回答
  2. 我是否需要像这样手动处理 MvxGridView 的每个单元格中的绑定:Clear bindings in MvvmCross?(绑定会自动绑定,因此这可能会偏离轨道。)

编辑

这是Environment.StackTrace来自 的变量DebugTrace.csMvxTextViewTextTargetBinding和的堆栈跟踪MvxWithEventPropertyInfoTargetBinding完全相同。(为了便于阅读,我删除了处理调用 IMvxTrace.Trace 的堆栈跟踪的前几行。)

   at Cirrious.MvvmCross.Binding.Bindings.Target.MvxPropertyInfoTargetBinding.SetValue(System.Object value)
   at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.UpdateTargetFromSource(Boolean isAvailable, System.Object value)
   at Cirrious.MvvmCross.Binding.Bindings.MvxFullBinding.<CreateSourceBinding>b__0(System.Object sender, Cirrious.MvvmCross.Binding.Bindings.Source.MvxSourcePropertyBindingEventArgs args)
   at Cirrious.MvvmCross.Binding.Bindings.SourceSteps.MvxSourceStep.SendSourcePropertyChanged(Boolean isAvailable, System.Object value)
   at Cirrious.MvvmCross.Binding.Bindings.SourceSteps.MvxPathSourceStep.SourceBindingOnChanged(System.Object sender, Cirrious.MvvmCross.Binding.Bindings.Source.MvxSourcePropertyBindingEventArgs args)
   at Cirrious.MvvmCross.Binding.Bindings.Source.MvxSourceBinding.FireChanged(Cirrious.MvvmCross.Binding.Bindings.Source.MvxSourcePropertyBindingEventArgs args)
   at Cirrious.MvvmCross.Binding.Bindings.Source.Leaf.MvxLeafPropertyInfoSourceBinding.OnBoundPropertyChanged()
   at Cirrious.MvvmCross.Binding.Bindings.Source.MvxPropertyInfoSourceBinding.SourcePropertyChanged(System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
   at System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod , System.Object , System.Object[] , System.Exception ByRef )
   at System.Reflection.MonoMethod.Invoke(System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture)
   at System.Reflection.MethodBase.Invoke(System.Object obj, System.Object[] parameters)
   at Cirrious.CrossCore.WeakSubscription.MvxWeakEventSubscription`2[[System.ComponentModel.INotifyPropertyChanged, System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.ComponentModel.PropertyChangedEventArgs, System, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].OnSourceEvent(System.Object sender, System.ComponentModel.PropertyChangedEventArgs e)
   at Cirrious.MvvmCross.ViewModels.MvxNotifyPropertyChanged+<>c__DisplayClass1.<RaisePropertyChanged>b__0()
   at Cirrious.CrossCore.Core.MvxMainThreadDispatcher.ExceptionMaskedAction(System.Action action)
   at Cirrious.MvvmCross.Droid.Views.MvxAndroidMainThreadDispatcher+<>c__DisplayClass1.<RequestMainThreadAction>b__0(System.Object ignored)
   at Android.App.SyncContext+<Post>c__AnonStorey2E.<>m__1F() in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/b76e8ec4/source/monodroid/src/Mono.Android/src/Android.App/SyncContext.cs:line 23
   at Java.Lang.Thread+RunnableImplementor.Run() in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/b76e8ec4/source/monodroid/src/Mono.Android/src/Java.Lang/Thread.cs:line 32
   at Java.Lang.IRunnableInvoker.n_Run(IntPtr jnienv, IntPtr native__this) in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.8.0-branch/b76e8ec4/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Java.Lang.IRunnable.cs:line 71
   at System.Object.ea853478-e8d0-4bbe-8306-98c58e64097e(IntPtr , IntPtr )
4

2 回答 2

2

我必须OnDestory()在显示MvxGridView.

public override void OnDestroy()
{
    MyProject.Core.ViewModel.MyViewModel vm = this.DataContext as MyProject.Core.ViewModel.MyViewModel;            
    base.OnDestroy();
    vm.Implode();
}

接下来我创建了一个如下所示的界面:

public interface IActiveViewModel
{
    /// <summary>
    /// Used to explicitly dispose of the viewModel
    /// </summary>
    void Implode();
}

其余代码位于关联的 View ModelMyViewModel中。

添加新的类接口:

public class MyViewModel : MvxViewModel, IActiveViewModel

并将这个函数也添加到类中:

public void Implode()
{
    if (MyGridTileViewModels != null)
    {
        foreach (GridTileViewModel vm in MyGridTileViewModels)
        {
            vm.Dispose();
        }
    }
    this.Dispose();
}

MyGridTileViewModels是绑定到的属性MvxGridView,它的定义如下:

private ObservableCollection<GridTileViewModel> _myGridTileViewModels = null;

public ObservableCollection<GridTileViewModel> MyGridTileViewModels 
{
    get { return _myGridTileViewModels; }
    protected set
    {
        // Set data and raise property changed here
    }
}
于 2013-09-13T16:58:38.963 回答
1

.1。是否可以从 MvvmCross 获得更详细的堆栈跟踪?

您的应用程序可能已经提供了它自己的DebugTrace实现 - 因此您可以在实现中提供您想要的任何其他跟踪信息。在 C# 中,可以使用 Environment.StackTrace 进行堆栈跟踪(但我从未在 MonoDroid 中使用过它——但我认为它可以工作!)

.2. 我是否需要手动处理 MvxGridView 的每个单元格中的绑定...?

MvxGridView 绑定通常会存储在拥有的 Activity(或 Fragment)中。编辑该 Activity 时应清除这些OnDestroy- 请参阅https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Droid/Views/MvxBindingActivityAdapter.cs#L49

每个单元格中的绑定将存储在单元格中。Disposed当该单元格为- https://github.com/slodge/MvvmCross/blob/v3/Cirrious/Cirrious.MvvmCross.Binding.Droid/Views/MvxBaseListItemView.cs#L42时,这些应该被清除- 时间已经下降到 Xamarin.Android,但自从 v4 MonoDroid 保证它在所有 Java.Lang.Object 派生对象上正确实现 IDisposable(请参阅 4.0 发行说明 - http://docs.xamarin.com/releases/android/mono_for_android_4/mono_for_android_4.0.0 )

我的猜测(从“绑定到一组视图模型,每个都有自己的绑定”)是,也许你的网格单元绑定到比 View/ViewModel 寿命更长的对象——不知何故,ViewModels 和它们的绑定是比包含视图/活动的生命周期更长。

当然,如果您愿意,您可以尽早清除任何绑定 - 尽管我对您的特定情况没有任何建议 - 目前代码太少而无法继续。作为第一步,我建议弄清楚是什么让你的 ViewModels 在内存中,而你的 Views 似乎成功地消失了。您详细的堆栈跟踪可能会对此有所帮助。

于 2013-09-06T07:11:09.117 回答