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中破坏了一些基本的东西?
我不知道您当前的问题与新的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);
}