mvvmcross在Mono上的意图

本文关键字:意图 Mono mvvmcross | 更新日期: 2023-09-27 18:02:20

我最近升级到运行在Windows上的Xamarin Studio。我有一个mvvmcross TipCalculator教程的简单实现,它在Android和各种Windows上运行得很好。我升级后,Android应用程序开始抛出NullReferenceExceptions在主活动(下面):

[Activity(Label = "TipCalculator.Android", MainLauncher = true, Icon = "@drawable/icon")]
public class TipCalculatorActivity : MvxBindingActivityView<TipCalculatorViewModel>
{
    protected override void OnViewModelSet()
    {
        SetContentView(Resource.Layout.TipView);//Throws NullReferenceException
    }
}

在深入研究mvvmcross代码之后,我在MvxAndroidViewsContainer类中发现了这个方法:

public virtual IMvxViewModel Load(Intent intent, Type viewModelTypeHint)
{
    if (intent == null)
    {
        // TODO - some trace here would be nice...
        return Activator.CreateInstance(viewModelTypeHint) as IMvxViewModel;
        //return null;
    }
    if (intent.Action == Intent.ActionMain)
    {
        // TODO - some trace here would be nice...
        return Activator.CreateInstance(viewModelTypeHint) as IMvxViewModel;
    }
    if (intent.Extras == null)
    {
        // TODO - some trace here would be nice...
        return Activator.CreateInstance(viewModelTypeHint) as IMvxViewModel;
        //return null;
    }
    IMvxViewModel mvxViewModel;
    if (TryGetEmbeddedViewModel(intent, out mvxViewModel))
        return mvxViewModel;
    return CreateViewModelFromIntent(intent);
}

在原始代码中,有两种情况返回null。在这些中,我将其替换为对Activator.CreateInstance()的调用。

我不确定原始实现背后的基本原理是什么,我有点担心我弄坏了什么东西。有人能解释一下为什么有些情况下这个方法返回null我是否在mvvmcross中破坏了一些基本的东西?

mvvmcross在Mono上的意图

我不知道您当前的问题与新的Xamarin工具有什么关系。你对NullReferenceExceptions的描述,改变的文件和博客文章让我失去了…

我猜在你的开发设置中可能有一些东西发生了变化,也许在你的应用程序中也是如此。如果你能一步一步地计算出来,也许你就能知道关键的变化是什么了。

这听起来像你的代码更改可能会修复可能会修复你当前的问题-但这绝对是一个补丁后应用的问题(无论它是什么)已经发生,所以这不是我想要在核心代码现在做的事情。


关于你所询问的代码:

        if (intent == null)
        {
            // TODO - some trace here would be nice...
            return null;
        }

这个第一个null只会发生,如果活动以某种方式被创建而没有意图-我想这不是发生?(除非在当前工具设置的某个地方,这以某种方式被设置为null?)


        if (intent.Action == Intent.ActionMain)
        {
            // TODO - some trace here would be nice...
            return Activator.CreateInstance(viewModelTypeHint) as IMvxViewModel;
        }

这是一个直接启动的活动的正常路径——这个活动将没有额外的参数来构造ViewModel。

一般来说,这个路径不会发生在许多MvvmCross应用程序中-大多数应用程序通过闪屏活动启动。


        if (intent.Extras == null)
        {
            // TODO - some trace here would be nice...
            return null;
        }

对于任何其他活动,Mvx应该插入一些特殊的ViewModel信息到Extras -所以没有办法Extras应该为空…如果发生这种情况,那么是什么代码在创建活动?


IMvxViewModel mvxViewModel;
if (TryGetEmbeddedViewModel(intent, out mvxViewModel))
    return mvxViewModel;
return CreateViewModelFromIntent(intent);

这是已导航到的活动的正常启动路径。


如果有帮助,下面是最新的v3代码—其中添加了一些跟踪(但也添加了savedState的混淆—现在忽略它!):

    public virtual IMvxViewModel Load(Intent intent, IMvxSavedState savedState, Type viewModelTypeHint)
    {
        if (intent == null)
        {
            MvxTrace.Trace(MvxTraceLevel.Error, "Null Intent seen when creating ViewModel");
            return null;
        }
        if (intent.Action == Intent.ActionMain)
        {
            MvxTrace.Trace("Creating ViewModel for ActionMain");
            return Activator.CreateInstance(viewModelTypeHint) as IMvxViewModel;
        }
        if (intent.Extras == null)
        {
            MvxTrace.Trace(MvxTraceLevel.Error, "Null Extras seen on Intent when creating ViewModel - this should not happen - have you tried to navigate to an MvvmCross View directly?");
            return null;
        }
        IMvxViewModel mvxViewModel;
        if (TryGetEmbeddedViewModel(intent, out mvxViewModel))
        {
            MvxTrace.Trace("Embedded ViewModel used");
            return mvxViewModel;
        }
        MvxTrace.Trace("Loading new ViewModel from Intent with Extras");
        return CreateViewModelFromIntent(intent, savedState);
    }