旋转期间的MvvmCross ViewModel生命周期

Rus*_*yCZ 6 mvvmcross

我一直在使用Mvvmcross来开发Android应用程序.我正在处理旋转期间ViewModel生命周期的问题.看起来通常在旋转期间保留ViewModel.但是,当我在MvxTabActivity中呈现ViewModels时,情况并非如此.当旋转发生时,它总是调用ViewModel构造函数.

我使用了与N + 1教程中类似的代码结构https://github.com/slodge/NPlus1DaysOfMvvmCross/tree/master/N-25-Tabbed.

有没有办法修改本教程,以便在使用MvxTabActivity时在旋转期间将ViewModel保留在内存中?

Stu*_*art 5

试图解决 Android 旋转行为的默认 ViewModel 缓存基于IMvxSingleViewModelCache- 因此它无法处理多个活动和多个 ViewModel 也就不足为奇了。

在哪里声明和使用这个接口,请参见https://github.com/slodge/MvvmCross/search?q=IMvxSingleViewModelCache&ref=cmdform

如果这种行为困扰着您,那么您应该可以通过以下方式之一解决它:

1. 使用基于片段的选项卡而不是基于活动的选项卡

Android 处理 Fragment 生命周期的方式与 Activity 不同。

2. 或者继续使用基于活动的选项卡,但实现自己的 IMvxSingleViewModelCache

例如,通过它们的“子”命名约定来识别您的子视图模型应该很简单。

完成此操作后,您可以实现以下内容:

public class MyCustomViewModelCache
    : IMvxSingleViewModelCache
{
    private const string BundleCacheKey = "__mvxVMCacheKey";

    private int _counter;

    private IMvxViewModel _currentViewModel;

    public void Cache(IMvxViewModel toCache, Bundle bundle)
    {
        if (toCache != null
            && toCache.GetType().Name.StartsWith("Child"))
        {
            // don't worry about caching child view models
            return;
        }

        _currentViewModel = toCache;
        _counter++;

        if (_currentViewModel == null)
        {
            return;
        }

        bundle.PutInt(BundleCacheKey, _counter);
    }

    public IMvxViewModel GetAndClear(Bundle bundle)
    {
        var storedViewModel = _currentViewModel;
        _currentViewModel = null;

        if (bundle == null)
            return null;

        var key = bundle.GetInt(BundleCacheKey);
        var toReturn = (key == _counter) ? storedViewModel : null;
        return toReturn;
    }
}
Run Code Online (Sandbox Code Playgroud)

此类基于MvxSingleViewModelCache.cs,仅添加了一个小功能。

您可以IMvxSingleViewModelCacheInitializeLastChance安装期间将此类的实例注册为单例。

  Mvx.RegisterSingleton<IMvxSingleViewModelCache>(new MyCustomViewModelCache());
    
Run Code Online (Sandbox Code Playgroud)

完成此操作后,home/tab 活动应该(我认为)继续工作 - 并且它会在旋转后将视图模型传递给选项卡子项。

(其他可能性IMvxSingleViewModelCache是可能的 - 例如它可以缓存多个视图模型 - 但请不要让它缓存太多视图模型太久,否则你可能会遇到“内存不足”的情况)

3. 或者关闭 Android 旋转处理

如果您添加android:configChanges="orientation"标志(或者它是 monodroid 等效属性),那么您可以自己处理旋转。