在一般导航中,MvvmCross 只允许在 ViewModel 之间传递字符串。
原因是导航需要通过 Xaml Uris 或 Android Intents 等机制在平台级别完成。
对于您建议的情况,我通常使用的一般模式是:
- TeamViewModel 使用注入的 ITeamService 从网络获取团队数据
- TeamViewModel 还使用注入的单例 ITeamCache 来缓存团队
- 导航是通过如下调用发生的:
this.RequestNavigate<PlayerViewModel>(new { teamId, playerId })
- PlayerViewModel 然后在其构造函数中接收 TeamId 和 PlayerId,并使用 ITeamCache 收集正确的玩家
此代码可能如下所示:
public class TeamViewModel
: MvxViewModel
, IMvxServiceConsumer<ITeamCache>
{
public TeamViewModel(string teamId, string playerId)
{
var teamCache = this.GetService<ITeamCache>();
Player = teamCache.GetPlayer(teamId, playerId);
if (Player == null)
{
// todo - handle this error somehow!
}
}
public Player Player { get; set; }
}
请注意,上面的代码测试 Player 是否为null
. 这是因为您的假设存在问题“在 TeamView 中,团队是深度加载的,因此玩家数据已经在内存中。”
问题在于,在 Android 和 WP7 等平台上,操作系统可以自由地将您的应用程序从内存中删除,然后再重新启动它。这在 WP7 上被称为Tombstoning ,但在 Android 上似乎被称为Killed 。
在这些情况下,操作系统可能会在用户返回时重新启动您的应用程序。此重新启动将直接转到用户上次所在的活动,并且它会记住返回堆栈 - 然后由您的应用程序将任何需要的对象正确地重新水化回内存。
这里有一些非常小的图片来解释这个......
有关更多详细信息,请参阅Xamarin和MSDN
对于您的团队/球员案例,您可以通过以下方式应对补液:
- 将 ITeamCache 实现为文件支持的对象 - 例如,它可以使用 JSON 文件或 SQLite 数据库作为内存数据的持久存储
- 在代码中实现一些逻辑,在需要时从网络重新获取数据
- 在这些情况下实施一些紧急导航回家策略——因为这些情况在现代资源丰富的手机上的许多应用程序中并不经常发生。
- 只是崩溃 - 虽然这是不可取的......
毫不奇怪,许多应用程序不能很好地处理墓碑......
注意 - 对于小对象,您的选项 3(序列化)可以很好地工作 - 但是,这不会帮助您解决应用程序补液并且用户随后从 PlayerViewModel 导航回 TeamViewModel 的情况。
有关 MvvmCross 中 Android 生命周期的一些最新变化的更多信息,请参阅http://slodge.blogspot.co.uk/2012/05/android-application-initialization-and.html